From 6b99eece103e00398c0fd6cdf3c4a4ebd00045b2 Mon Sep 17 00:00:00 2001
From: dobromir-hristov <dobromir92@gmail.com>
Date: Sun, 26 Apr 2020 23:47:01 +0300
Subject: [PATCH 1/3] feat: add config to show deprecation warnings

---
 flow/config.flow.js                           |  3 +-
 package.json                                  |  4 +-
 .../create-instance/create-component-stubs.js |  4 +-
 packages/shared/merge-options.js              |  9 +--
 packages/shared/util.js                       |  8 +++
 packages/test-utils/package.json              |  2 +-
 packages/test-utils/scripts/build.js          |  6 ++
 packages/test-utils/src/config.js             |  6 +-
 packages/test-utils/src/wrapper.js            | 64 ++++++++++++-------
 packages/test-utils/types/index.d.ts          |  3 +-
 test/specs/config.spec.js                     | 15 +++++
 test/specs/mounting-options/slots.spec.js     |  2 +-
 yarn.lock                                     | 48 +++++++++++++-
 13 files changed, 134 insertions(+), 40 deletions(-)

diff --git a/flow/config.flow.js b/flow/config.flow.js
index 3b8ca796f..a53bb381d 100644
--- a/flow/config.flow.js
+++ b/flow/config.flow.js
@@ -3,5 +3,6 @@ declare type Config = {
   mocks?: Object,
   methods?: { [name: string]: Function },
   provide?: Object,
-  silent?: boolean
+  silent?: boolean,
+  showDeprecationWarnings?: boolean
 }
diff --git a/package.json b/package.json
index 38b9b35bd..a47afe21f 100644
--- a/package.json
+++ b/package.json
@@ -98,7 +98,9 @@
     "cz-conventional-changelog": "^3.0.2",
     "husky": "^3.1.0",
     "lint-staged": "^9.5.0",
-    "prettier": "^1.16.0"
+    "prettier": "^1.16.0",
+    "rollup-plugin-delete": "^1.2.0",
+    "rollup-plugin-replace": "^2.2.0"
   },
   "config": {
     "commitizen": {
diff --git a/packages/create-instance/create-component-stubs.js b/packages/create-instance/create-component-stubs.js
index a5de8e315..c3c11fab7 100644
--- a/packages/create-instance/create-component-stubs.js
+++ b/packages/create-instance/create-component-stubs.js
@@ -7,7 +7,7 @@ import {
   capitalize,
   hyphenate,
   keys,
-  warn
+  warnDeprecated
 } from '../shared/util'
 import {
   componentNeedsCompiling,
@@ -159,7 +159,7 @@ export function createStubFromComponent(
 
 // DEPRECATED: converts string stub to template stub.
 function createStubFromString(templateString: string, name: string): Component {
-  warn('String stubs are deprecated and will be removed in future versions')
+  warnDeprecated('Using a string for stubs')
 
   if (templateContainsComponent(templateString, name)) {
     throwError('options.stub cannot contain a circular reference')
diff --git a/packages/shared/merge-options.js b/packages/shared/merge-options.js
index a1ba05d6a..93c5e6dab 100644
--- a/packages/shared/merge-options.js
+++ b/packages/shared/merge-options.js
@@ -1,6 +1,6 @@
 // @flow
 import { normalizeStubs, normalizeProvide } from './normalize'
-import { warn } from 'shared/util'
+import { warnDeprecated } from 'shared/util'
 
 function getOption(option, config?: Object): any {
   if (option === false) {
@@ -34,11 +34,8 @@ export function mergeOptions(
   const methods = (getOption(options.methods, config.methods): {
     [key: string]: Function
   })
-
-  if (config.methods && Object.keys(config.methods).length) {
-    warn(
-      `config.methods has been deprecated. It will be removed in a future release`
-    )
+  if (methods && Object.keys(methods).length) {
+    warnDeprecated('overwriting methods via the `methods` property')
   }
 
   const provide = (getOption(options.provide, config.provide): Object)
diff --git a/packages/shared/util.js b/packages/shared/util.js
index dfa362945..d8c942796 100644
--- a/packages/shared/util.js
+++ b/packages/shared/util.js
@@ -1,6 +1,7 @@
 // @flow
 import Vue from 'vue'
 import semver from 'semver'
+import { config } from '@vue/test-utils'
 
 export function throwError(msg: string): void {
   throw new Error(`[vue-test-utils]: ${msg}`)
@@ -85,3 +86,10 @@ export function getCheckedEvent() {
   // change is handler for version 2.0 - 2.1.8, and 2.5+
   return 'change'
 }
+
+export function warnDeprecated(method: string, fallback: string = '') {
+  if (!config.showDeprecationWarnings) return
+  let msg = `${method} is deprecated and will removed in the next major version`
+  if (fallback) msg += ` ${fallback}`
+  warn(msg)
+}
diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json
index e224df063..a3d2f3b71 100644
--- a/packages/test-utils/package.json
+++ b/packages/test-utils/package.json
@@ -10,7 +10,7 @@
   ],
   "scripts": {
     "build": "node scripts/build.js",
-    "build:test": "cross-env NODE_ENV=test node scripts/build.js"
+    "build:test": "cross-env NODE_ENV=test SHOW_DEPRECATIONS=false node scripts/build.js"
   },
   "repository": {
     "type": "git",
diff --git a/packages/test-utils/scripts/build.js b/packages/test-utils/scripts/build.js
index 337ab94cc..7d50a0369 100644
--- a/packages/test-utils/scripts/build.js
+++ b/packages/test-utils/scripts/build.js
@@ -6,6 +6,8 @@ const nodeResolve = require('rollup-plugin-node-resolve')
 const commonjs = require('rollup-plugin-commonjs')
 const chalk = require('chalk')
 const json = require('rollup-plugin-json')
+const replace = require('rollup-plugin-replace')
+const del = require('rollup-plugin-delete')
 
 function success(text) {
   console.log(chalk.green(`${text} ✔`))
@@ -57,6 +59,10 @@ rollupOptions.forEach(options => {
     input: resolve('src/index.js'),
     external: ['vue', 'vue-template-compiler'],
     plugins: [
+      del({ targets: 'dist/*' }),
+      replace({
+        'process.env.SHOW_DEPRECATIONS': process.env.SHOW_DEPRECATIONS
+      }),
       flow(),
       json(),
       buble({
diff --git a/packages/test-utils/src/config.js b/packages/test-utils/src/config.js
index dca576c28..680e92b2a 100644
--- a/packages/test-utils/src/config.js
+++ b/packages/test-utils/src/config.js
@@ -6,5 +6,9 @@ export default {
   mocks: {},
   methods: {},
   provide: {},
-  silent: true
+  silent: true,
+  showDeprecationWarnings:
+    typeof process.env.SHOW_DEPRECATIONS !== 'undefined'
+      ? process.env.SHOW_DEPRECATIONS
+      : true
 }
diff --git a/packages/test-utils/src/wrapper.js b/packages/test-utils/src/wrapper.js
index 7fa5699e8..5ed371163 100644
--- a/packages/test-utils/src/wrapper.js
+++ b/packages/test-utils/src/wrapper.js
@@ -12,7 +12,12 @@ import {
 import config from './config'
 import WrapperArray from './wrapper-array'
 import ErrorWrapper from './error-wrapper'
-import { throwError, getCheckedEvent, isPhantomJS, warn } from 'shared/util'
+import {
+  throwError,
+  getCheckedEvent,
+  isPhantomJS,
+  warnDeprecated
+} from 'shared/util'
 import find from './find'
 import createWrapper from './create-wrapper'
 import { recursivelySetData } from './recursively-set-data'
@@ -122,8 +127,9 @@ export default class Wrapper implements BaseWrapper {
    * Checks if wrapper contains provided selector.
    */
   contains(rawSelector: Selector): boolean {
-    warn(
-      'contains is deprecated and will be removed in a future release. Use `wrapper.find`, `wrapper.findComponent` or `wrapper.get` instead'
+    warnDeprecated(
+      'contains',
+      'Use `wrapper.find`, `wrapper.findComponent` or `wrapper.get` instead'
     )
     const selector = getSelector(rawSelector, 'contains')
     const nodes = find(this.rootNode, this.vm, selector)
@@ -171,9 +177,7 @@ export default class Wrapper implements BaseWrapper {
    * Returns an Array containing custom events emitted by the Wrapper vm
    */
   emittedByOrder(): Array<{ name: string, args: Array<any> }> {
-    warn(
-      'emittedByOrder is deprecated and will be removed in a future release. Use `wrapper.emitted` instead'
-    )
+    warnDeprecated('emittedByOrder', 'Use `wrapper.emitted` instead')
     if (!this._emittedByOrder && !this.vm) {
       throwError(
         `wrapper.emittedByOrder() can only be called on a Vue instance`
@@ -201,9 +205,6 @@ export default class Wrapper implements BaseWrapper {
    * matches the provided selector.
    */
   get(rawSelector: Selector): Wrapper {
-    warn(
-      'get is deprecated and will be removed in a future release. Use `find` or `findComponent` instead'
-    )
     const found = this.find(rawSelector)
     if (found instanceof ErrorWrapper) {
       throw new Error(`Unable to find ${rawSelector} within: ${this.html()}`)
@@ -218,8 +219,9 @@ export default class Wrapper implements BaseWrapper {
   find(rawSelector: Selector): Wrapper | ErrorWrapper {
     const selector = getSelector(rawSelector, 'find')
     if (selector.type !== DOM_SELECTOR) {
-      warn(
-        'finding components with `find` is deprecated and will be removed in a future release. Use `findComponent` instead'
+      warnDeprecated(
+        'finding components with `find`',
+        'Use `findComponent` instead'
       )
     }
     const node = find(this.rootNode, this.vm, selector)[0]
@@ -240,8 +242,9 @@ export default class Wrapper implements BaseWrapper {
   findAll(rawSelector: Selector): WrapperArray {
     const selector = getSelector(rawSelector, 'findAll')
     if (selector.type !== DOM_SELECTOR) {
-      warn(
-        'finding components with `findAll` is deprecated and will be removed in a future release. Use `findAllComponents` instead'
+      warnDeprecated(
+        'finding components with `findAll`',
+        'Use `findAllComponents` instead'
       )
     }
     const nodes = find(this.rootNode, this.vm, selector)
@@ -316,9 +319,7 @@ export default class Wrapper implements BaseWrapper {
    * Checks if node matches selector
    */
   is(rawSelector: Selector): boolean {
-    warn(
-      `is is deprecated and will be removed in a future release. Use element.tagName instead`
-    )
+    warnDeprecated('is', 'Use element.tagName instead')
     const selector = getSelector(rawSelector, 'is')
 
     if (selector.type === REF_SELECTOR) {
@@ -332,9 +333,9 @@ export default class Wrapper implements BaseWrapper {
    * Checks if node is empty
    */
   isEmpty(): boolean {
-    warn(
-      `isEmpty is deprecated and will be removed in a future release. ` +
-        `Consider a custom matcher such as those provided in jest-dom: https://github.com/testing-library/jest-dom#tobeempty`
+    warnDeprecated(
+      'isEmpty',
+      'Consider a custom matcher such as those provided in jest-dom: https://github.com/testing-library/jest-dom#tobeempty'
     )
     if (!this.vnode) {
       return this.element.innerHTML === ''
@@ -360,8 +361,10 @@ export default class Wrapper implements BaseWrapper {
    * Checks if node is visible
    */
   isVisible(): boolean {
-    warn(`isEmpty is deprecated and will be removed in a future release.
-      Consider a custom matcher such as those provided in jest-dom: https://github.com/testing-library/jest-dom#tobevisible`)
+    warnDeprecated(
+      'isEmpty',
+      `Consider a custom matcher such as those provided in jest-dom: https://github.com/testing-library/jest-dom#tobevisible`
+    )
     let element = this.element
     while (element) {
       if (
@@ -382,7 +385,7 @@ export default class Wrapper implements BaseWrapper {
    * Checks if wrapper is a vue instance
    */
   isVueInstance(): boolean {
-    warn(`isVueInstance is deprecated and will be removed in a future release`)
+    warnDeprecated(`isVueInstance`)
     return !!this.vm
   }
 
@@ -390,6 +393,8 @@ export default class Wrapper implements BaseWrapper {
    * Returns name of component, or tag name if node is not a Vue component
    */
   name(): string {
+    warnDeprecated(`name`)
+
     if (this.vm) {
       return (
         this.vm.$options.name ||
@@ -410,6 +415,8 @@ export default class Wrapper implements BaseWrapper {
    * with useful information for debugging
    */
   overview(): void {
+    warnDeprecated(`overview`)
+
     if (!this.isVueInstance()) {
       throwError(`wrapper.overview() can only be called on a Vue instance`)
     }
@@ -511,6 +518,11 @@ export default class Wrapper implements BaseWrapper {
    * Checks radio button or checkbox element
    */
   setChecked(checked: boolean = true): void {
+    warnDeprecated(
+      `setChecked`,
+      'When you migrate to VTU 2, use setValue instead.'
+    )
+
     if (typeof checked !== 'boolean') {
       throwError('wrapper.setChecked() must be passed a boolean')
     }
@@ -558,6 +570,11 @@ export default class Wrapper implements BaseWrapper {
    * Selects <option></option> element
    */
   setSelected(): void {
+    warnDeprecated(
+      `setSelected`,
+      'When you migrate to VTU 2, use setValue instead.'
+    )
+
     const tagName = this.element.tagName
 
     if (tagName === 'SELECT') {
@@ -610,7 +627,8 @@ export default class Wrapper implements BaseWrapper {
    * Sets vm methods
    */
   setMethods(methods: Object): void {
-    warn(`setMethods is deprecated and will be removed in a future release`)
+    warnDeprecated(`setMethods`)
+
     if (!this.isVueInstance()) {
       throwError(`wrapper.setMethods() can only be called on a Vue instance`)
     }
diff --git a/packages/test-utils/types/index.d.ts b/packages/test-utils/types/index.d.ts
index 8b67d2ffd..bc5a6bdc4 100644
--- a/packages/test-utils/types/index.d.ts
+++ b/packages/test-utils/types/index.d.ts
@@ -150,7 +150,8 @@ interface VueTestUtilsConfigOptions {
   mocks?: Record<string, any>
   methods?: Record<string, Function>
   provide?: Record<string, any>,
-  silent?: Boolean
+  silent?: Boolean,
+  showDeprecationWarnings?: boolean
 }
 
 export declare function createLocalVue (): typeof Vue
diff --git a/test/specs/config.spec.js b/test/specs/config.spec.js
index 3f44751a1..42456fd92 100644
--- a/test/specs/config.spec.js
+++ b/test/specs/config.spec.js
@@ -17,6 +17,7 @@ describeWithShallowAndMount('config', mountingMethod => {
   afterEach(() => {
     config.stubs = configStubsSave
     config.silent = configSilentSave
+    config.methods = {}
     sandbox.reset()
     sandbox.restore()
   })
@@ -99,4 +100,18 @@ describeWithShallowAndMount('config', mountingMethod => {
     await wrapper.vm.$nextTick()
     expect(wrapper.find('[data-testid="expanded"]').exists()).to.equal(false)
   })
+
+  it('allows control deprecation warnings visibility', () => {
+    config.showDeprecationWarnings = true
+    const Component = {
+      name: 'Foo',
+      template: '<div>Foo</div>'
+    }
+    const wrapper = mountingMethod(Component)
+    wrapper.name()
+    expect(console.error).to.be.calledWith(sandbox.match('name is deprecated'))
+    config.showDeprecationWarnings = false
+    wrapper.name()
+    expect(console.error).to.have.callCount(1)
+  })
 })
diff --git a/test/specs/mounting-options/slots.spec.js b/test/specs/mounting-options/slots.spec.js
index ee1477063..1fc2ddd9d 100644
--- a/test/specs/mounting-options/slots.spec.js
+++ b/test/specs/mounting-options/slots.spec.js
@@ -343,7 +343,7 @@ describeWithShallowAndMount('options.slots', mountingMethod => {
       .with.property('message', message)
   })
 
-  it('throws error if passed a number for named slots', () => {
+  it('throws error if passed an array of numbers for named slots', () => {
     const TestComponent = {
       name: 'component-with-slots',
       functional: true,
diff --git a/yarn.lock b/yarn.lock
index c1086a1a2..1f80eba4b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4963,6 +4963,19 @@ del@^2.0.2:
     pinkie-promise "^2.0.0"
     rimraf "^2.2.8"
 
+del@^4.1.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4"
+  integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==
+  dependencies:
+    "@types/glob" "^7.1.1"
+    globby "^6.1.0"
+    is-path-cwd "^2.0.0"
+    is-path-in-cwd "^2.0.0"
+    p-map "^2.0.0"
+    pify "^4.0.1"
+    rimraf "^2.6.3"
+
 del@^5.0.0:
   version "5.1.0"
   resolved "https://registry.yarnpkg.com/del/-/del-5.1.0.tgz#d9487c94e367410e6eff2925ee58c0c84a75b3a7"
@@ -7420,7 +7433,7 @@ is-path-cwd@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
 
-is-path-cwd@^2.2.0:
+is-path-cwd@^2.0.0, is-path-cwd@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb"
   integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==
@@ -7431,12 +7444,26 @@ is-path-in-cwd@^1.0.0:
   dependencies:
     is-path-inside "^1.0.0"
 
+is-path-in-cwd@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb"
+  integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==
+  dependencies:
+    is-path-inside "^2.1.0"
+
 is-path-inside@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
   dependencies:
     path-is-inside "^1.0.1"
 
+is-path-inside@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2"
+  integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==
+  dependencies:
+    path-is-inside "^1.0.2"
+
 is-path-inside@^3.0.1:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017"
@@ -8043,7 +8070,7 @@ leb@^0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/leb/-/leb-0.3.0.tgz#32bee9fad168328d6aea8522d833f4180eed1da3"
 
-lerna@3.20.2:
+lerna@^3.20.2:
   version "3.20.2"
   resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.20.2.tgz#abf84e73055fe84ee21b46e64baf37b496c24864"
   integrity sha512-bjdL7hPLpU3Y8CBnw/1ys3ynQMUjiK6l9iDWnEGwFtDy48Xh5JboR9ZJwmKGCz9A/sarVVIGwf1tlRNKUG9etA==
@@ -11233,6 +11260,13 @@ rollup-plugin-commonjs@10:
     resolve "^1.11.0"
     rollup-pluginutils "^2.8.1"
 
+rollup-plugin-delete@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/rollup-plugin-delete/-/rollup-plugin-delete-1.2.0.tgz#a7e45ca4c5480308fa355d11de622f22e7075e12"
+  integrity sha512-k2vHnECLSVpT1OqK2wblt+ZIxJ7dmnaaYdb6AsBRpl4Ilpy10ibSnXVD7nJTRaB7KRP02XDRt0SCZ8vWi+VPdQ==
+  dependencies:
+    del "^4.1.1"
+
 rollup-plugin-flow-no-whitespace@1:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/rollup-plugin-flow-no-whitespace/-/rollup-plugin-flow-no-whitespace-1.0.0.tgz#bd4ba1bcd99ad5b88234d72e6e2dacea9aa02d16"
@@ -11259,6 +11293,14 @@ rollup-plugin-node-resolve@5:
     resolve "^1.11.1"
     rollup-pluginutils "^2.8.1"
 
+rollup-plugin-replace@^2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/rollup-plugin-replace/-/rollup-plugin-replace-2.2.0.tgz#f41ae5372e11e7a217cde349c8b5d5fd115e70e3"
+  integrity sha512-/5bxtUPkDHyBJAKketb4NfaeZjL5yLZdeUihSfbF2PQMz+rSTEb8ARKoOl3UBT4m7/X+QOXJo3sLTcq+yMMYTA==
+  dependencies:
+    magic-string "^0.25.2"
+    rollup-pluginutils "^2.6.0"
+
 rollup-pluginutils@^1.5.2:
   version "1.5.2"
   resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408"
@@ -11266,7 +11308,7 @@ rollup-pluginutils@^1.5.2:
     estree-walker "^0.2.1"
     minimatch "^3.0.2"
 
-rollup-pluginutils@^2.3.3, rollup-pluginutils@^2.5.0, rollup-pluginutils@^2.8.1:
+rollup-pluginutils@^2.3.3, rollup-pluginutils@^2.5.0, rollup-pluginutils@^2.6.0, rollup-pluginutils@^2.8.1:
   version "2.8.2"
   resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e"
   integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==

From 5eac9cf1e8b6774a98dd4e63cdf980171ad42215 Mon Sep 17 00:00:00 2001
From: dobromir-hristov <dobromir92@gmail.com>
Date: Mon, 27 Apr 2020 00:03:28 +0300
Subject: [PATCH 2/3] test: fix failing deprecated test

---
 test/specs/mounting-options/stubs.spec.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/test/specs/mounting-options/stubs.spec.js b/test/specs/mounting-options/stubs.spec.js
index 8c8715462..da081bb38 100644
--- a/test/specs/mounting-options/stubs.spec.js
+++ b/test/specs/mounting-options/stubs.spec.js
@@ -630,6 +630,7 @@ describeWithShallowAndMount('options.stub', mountingMethod => {
   )
 
   it('warns when passing a string', () => {
+    config.showDeprecationWarnings = true
     const StringComponent = '<div></div>'
     mountingMethod(ComponentWithChild, {
       stubs: {
@@ -638,9 +639,8 @@ describeWithShallowAndMount('options.stub', mountingMethod => {
     })
 
     expect(console.error).calledWith(
-      sandbox.match(
-        '[vue-test-utils]: String stubs are deprecated and will be removed in future versions'
-      )
+      sandbox.match('[vue-test-utils]: Using a string for stubs is deprecated')
     )
+    config.showDeprecationWarnings = false
   })
 })

From 782ba111965ba7cd57076258a9e643c66048bd74 Mon Sep 17 00:00:00 2001
From: Lachlan Miller <lachlan.miller.1990@outlook.com>
Date: Mon, 27 Apr 2020 19:34:56 +1000
Subject: [PATCH 3/3] test: skip tests in old version of vue

---
 test/specs/wrapper/setMethods.spec.js | 29 ++++++++++++++++-----------
 test/specs/wrapper/trigger.spec.js    | 23 ++++++++++++---------
 2 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/test/specs/wrapper/setMethods.spec.js b/test/specs/wrapper/setMethods.spec.js
index b6457b181..1907950e9 100644
--- a/test/specs/wrapper/setMethods.spec.js
+++ b/test/specs/wrapper/setMethods.spec.js
@@ -1,7 +1,8 @@
 import { compileToFunctions } from 'vue-template-compiler'
 import ComponentWithMethods from '~resources/components/component-with-methods.vue'
 import ComponentWithEvents from '~resources/components/component-with-events.vue'
-import { describeWithShallowAndMount } from '~resources/utils'
+import { describeWithShallowAndMount, vueVersion } from '~resources/utils'
+import { itDoNotRunIf } from 'conditional-specs'
 
 describeWithShallowAndMount('setMethods', mountingMethod => {
   it('sets component data and updates nested vm nodes when called on Vue instance', () => {
@@ -19,15 +20,19 @@ describeWithShallowAndMount('setMethods', mountingMethod => {
     expect(() => p.setMethods({ ready: true })).throw(Error, message)
   })
 
-  it('should replace methods when tied to an event', () => {
-    const wrapper = mountingMethod(ComponentWithEvents)
-    expect(wrapper.vm.isActive).to.be.false
-    wrapper.find('.toggle').trigger('click')
-    expect(wrapper.vm.isActive).to.be.true
-    // Replace the toggle function so that the data supposedly won't change
-    const toggleActive = () => {}
-    wrapper.setMethods({ toggleActive })
-    wrapper.find('.toggle').trigger('click')
-    expect(wrapper.vm.isActive).to.be.true
-  })
+  itDoNotRunIf(
+    vueVersion < 2.2,
+    'should replace methods when tied to an event',
+    () => {
+      const wrapper = mountingMethod(ComponentWithEvents)
+      expect(wrapper.vm.isActive).to.be.false
+      wrapper.find('.toggle').trigger('click')
+      expect(wrapper.vm.isActive).to.be.true
+      // Replace the toggle function so that the data supposedly won't change
+      const toggleActive = () => {}
+      wrapper.setMethods({ toggleActive })
+      wrapper.find('.toggle').trigger('click')
+      expect(wrapper.vm.isActive).to.be.true
+    }
+  )
 })
diff --git a/test/specs/wrapper/trigger.spec.js b/test/specs/wrapper/trigger.spec.js
index d6b3ee1a4..268b2b89a 100644
--- a/test/specs/wrapper/trigger.spec.js
+++ b/test/specs/wrapper/trigger.spec.js
@@ -3,7 +3,8 @@ import ComponentWithScopedSlots from '~resources/components/component-with-scope
 import {
   describeWithShallowAndMount,
   scopedSlotsSupported,
-  isRunningPhantomJS
+  isRunningPhantomJS,
+  vueVersion
 } from '~resources/utils'
 import Vue from 'vue'
 import { itDoNotRunIf } from 'conditional-specs'
@@ -96,14 +97,18 @@ describeWithShallowAndMount('trigger', mountingMethod => {
     }
   })
 
-  it('causes DOM to update after clickHandler method that changes components data is called', async () => {
-    const wrapper = mountingMethod(ComponentWithEvents)
-    const toggle = wrapper.find('.toggle')
-    expect(toggle.classes()).not.to.contain('active')
-    toggle.trigger('click')
-    await Vue.nextTick()
-    expect(toggle.classes()).to.contain('active')
-  })
+  itDoNotRunIf(
+    vueVersion < 2.2,
+    'causes DOM to update after clickHandler method that changes components data is called',
+    async () => {
+      const wrapper = mountingMethod(ComponentWithEvents)
+      const toggle = wrapper.find('.toggle')
+      expect(toggle.classes()).not.to.contain('active')
+      toggle.trigger('click')
+      await Vue.nextTick()
+      expect(toggle.classes()).to.contain('active')
+    }
+  )
 
   it('adds options to event', () => {
     const clickHandler = sandbox.stub()