From 6b2d44416d1d8af25fc33e65af1f98ca22c84f96 Mon Sep 17 00:00:00 2001 From: Alex Khomenko Date: Thu, 20 Aug 2020 16:21:42 +0300 Subject: [PATCH] Testing: Use React Testing Library (#27072) * Add RTL * Add setupTests.ts * Refactor DashboardSearch tests --- jest.config.js | 1 + package.json | 3 + .../core/components/TagFilter/TagFilter.tsx | 2 +- .../components/DashboardSearch.test.tsx | 115 ++++++++-------- .../app/features/search/components/mocks.ts | 10 +- public/test/setupTests.ts | 1 + yarn.lock | 124 +++++++++++++++++- 7 files changed, 190 insertions(+), 66 deletions(-) create mode 100644 public/test/setupTests.ts diff --git a/jest.config.js b/jest.config.js index a349c3f17e7..63d2702ace7 100644 --- a/jest.config.js +++ b/jest.config.js @@ -12,6 +12,7 @@ module.exports = { testRegex: '(\\.|/)(test)\\.(jsx?|tsx?)$', moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], setupFiles: ['jest-canvas-mock', './public/test/jest-shim.ts', './public/test/jest-setup.ts'], + setupFilesAfterEnv: ['./public/test/setupTests.ts'], snapshotSerializers: ['enzyme-to-json/serializer'], globals: { 'ts-jest': { isolatedModules: true } }, moduleNameMapper: { diff --git a/package.json b/package.json index 4a978009585..74387ba9917 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,8 @@ "@grafana/eslint-config": "2.0.0", "@microsoft/api-extractor": "7.8.2-pr1796.0", "@rtsao/plugin-proposal-class-properties": "7.0.1-patch.1", + "@testing-library/jest-dom": "^5.11.3", + "@testing-library/react": "^10.4.8", "@testing-library/react-hooks": "^3.2.1", "@types/angular": "1.6.56", "@types/angular-route": "1.7.0", @@ -112,6 +114,7 @@ "@types/slate": "0.47.1", "@types/slate-plain-serializer": "0.6.1", "@types/slate-react": "0.22.5", + "@types/testing-library__jest-dom": "^5.9.2", "@types/testing-library__react-hooks": "^3.2.0", "@types/tinycolor2": "1.4.2", "@typescript-eslint/eslint-plugin": "3.6.0", diff --git a/public/app/core/components/TagFilter/TagFilter.tsx b/public/app/core/components/TagFilter/TagFilter.tsx index b5daffe2440..66072475c78 100644 --- a/public/app/core/components/TagFilter/TagFilter.tsx +++ b/public/app/core/components/TagFilter/TagFilter.tsx @@ -93,7 +93,7 @@ export const TagFilter: FC = ({ }; return ( -
+
{isClearable && tags.length > 0 && ( onTagChange([])}> Clear tags diff --git a/public/app/features/search/components/DashboardSearch.test.tsx b/public/app/features/search/components/DashboardSearch.test.tsx index edc7a7d5bec..210f4a3dc3e 100644 --- a/public/app/features/search/components/DashboardSearch.test.tsx +++ b/public/app/features/search/components/DashboardSearch.test.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { mount } from 'enzyme'; -import { act } from 'react-dom/test-utils'; +import { render, fireEvent, screen, waitFor, act } from '@testing-library/react'; import { mockSearch } from './mocks'; import { DashboardSearch, Props } from './DashboardSearch'; import { searchResults } from '../testData'; @@ -15,18 +14,13 @@ afterEach(() => { jest.useRealTimers(); }); -const setup = async (testProps?: Partial): Promise => { +const setup = (testProps?: Partial) => { const props: any = { onCloseSearch: () => {}, ...testProps, }; - let wrapper; - //@ts-ignore - await act(async () => { - wrapper = await mount(); - jest.runAllTimers(); - }); - return wrapper; + render(); + jest.runAllTimers(); }; /** @@ -35,7 +29,9 @@ const setup = async (testProps?: Partial): Promise => { */ describe('DashboardSearch', () => { it('should call search api with default query when initialised', async () => { - await setup(); + setup(); + + await waitFor(() => screen.getByPlaceholderText('Search dashboards by name')); expect(mockSearch).toHaveBeenCalledTimes(1); expect(mockSearch).toHaveBeenCalledWith({ @@ -51,19 +47,13 @@ describe('DashboardSearch', () => { }); it('should call api with updated query on query change', async () => { - let wrapper = await setup(); - - //@ts-ignore - await act(async () => { - // @ts-ignore - await wrapper - .find({ placeholder: 'Search dashboards by name' }) - .hostNodes() - //@ts-ignore - .prop('onChange')({ currentTarget: { value: 'Test' } }); + setup(); + const input = await screen.findByPlaceholderText('Search dashboards by name'); + await act((async () => { + await fireEvent.input(input, { target: { value: 'Test' } }); jest.runAllTimers(); - }); + }) as any); expect(mockSearch).toHaveBeenCalledWith({ query: 'Test', @@ -78,58 +68,61 @@ describe('DashboardSearch', () => { }); it("should render 'No results' message when there are no dashboards", async () => { - let wrapper = await setup(); + setup(); - wrapper.update(); - expect( - wrapper - .findWhere((c: any) => c.type() === 'div' && c.text() === 'No dashboards matching your query were found.') - .exists() - ).toBe(true); + const message = await screen.findByText('No dashboards matching your query were found.'); + expect(message).toBeInTheDocument(); }); it('should render search results', async () => { - //@ts-ignore - mockSearch.mockImplementation(() => Promise.resolve(searchResults)); - let wrapper = await setup(); - wrapper.update(); - expect(wrapper.find({ 'aria-label': 'Search section' })).toHaveLength(2); - expect(wrapper.find({ 'aria-label': 'Search items' }).children()).toHaveLength(2); + mockSearch.mockResolvedValueOnce(searchResults); + + setup(); + const section = await screen.findAllByLabelText('Search section'); + expect(section).toHaveLength(2); + expect(screen.getAllByLabelText('Search items')).toHaveLength(2); }); it('should call search with selected tags', async () => { - let wrapper = await setup(); + setup(); - //@ts-ignore - await act(async () => { - //@ts-ignore - await wrapper.find('TagFilter').prop('onChange')(['TestTag']); - jest.runAllTimers(); - }); + await waitFor(() => screen.getByLabelText('Tag filter')); + // Get the actual element for the underlying Select component, since Select doesn't accept aria- props + const tagComponent = screen.getByLabelText('Tag filter').querySelector('div') as Node; + fireEvent.keyDown(tagComponent, { keyCode: 40 }); - expect(mockSearch).toHaveBeenCalledWith({ - query: '', - skipRecent: false, - skipStarred: false, - tag: ['TestTag'], - starred: false, - folderIds: [], - layout: SearchLayout.Folders, - sort: undefined, - }); + await waitFor(() => screen.getByText('tag1')); + fireEvent.click(screen.getByText('tag1')); + + expect(tagComponent).toBeInTheDocument(); + + await waitFor(() => + expect(mockSearch).toHaveBeenCalledWith({ + query: '', + skipRecent: false, + skipStarred: false, + tag: ['tag1'], + starred: false, + folderIds: [], + layout: SearchLayout.Folders, + sort: undefined, + }) + ); }); it('should call search api with provided search params', async () => { const params = { query: 'test query', tag: ['tag1'], sort: { value: 'asc' } }; - await setup({ params }); + setup({ params }); - expect(mockSearch).toHaveBeenCalledTimes(1); - expect(mockSearch).toHaveBeenCalledWith( - expect.objectContaining({ - query: 'test query', - tag: ['tag1'], - sort: 'asc', - }) - ); + await waitFor(() => { + expect(mockSearch).toHaveBeenCalledTimes(1); + expect(mockSearch).toHaveBeenCalledWith( + expect.objectContaining({ + query: 'test query', + tag: ['tag1'], + sort: 'asc', + }) + ); + }); }); }); diff --git a/public/app/features/search/components/mocks.ts b/public/app/features/search/components/mocks.ts index c98fb4d7218..e9340325eed 100644 --- a/public/app/features/search/components/mocks.ts +++ b/public/app/features/search/components/mocks.ts @@ -1,12 +1,18 @@ -export const mockSearch = jest.fn(() => { +export const mockSearch = jest.fn(() => { return Promise.resolve([]); }); + jest.mock('app/core/services/search_srv', () => { return { SearchSrv: jest.fn().mockImplementation(() => { return { search: mockSearch, - getDashboardTags: jest.fn(() => Promise.resolve(['Tag1', 'Tag2'])), + getDashboardTags: jest.fn(() => + Promise.resolve([ + { term: 'tag1', count: 2 }, + { term: 'tag2', count: 10 }, + ]) + ), getSortOptions: jest.fn(() => Promise.resolve({ sortOptions: [{ name: 'test', displayName: 'Test' }] })), }; }), diff --git a/public/test/setupTests.ts b/public/test/setupTests.ts new file mode 100644 index 00000000000..7b0828bfa80 --- /dev/null +++ b/public/test/setupTests.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom'; diff --git a/yarn.lock b/yarn.lock index 21f8827d965..35300a95f31 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2727,6 +2727,14 @@ pirates "^4.0.0" source-map-support "^0.5.16" +"@babel/runtime-corejs3@^7.10.2": + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.11.2.tgz#02c3029743150188edeb66541195f54600278419" + integrity sha512-qh5IR+8VgFz83VBa6OkaET6uN/mJOhHONuy3m1sgF0CV6mXdPSEBdA7e1eUbVvyNtANjMbg22JUv71BaDXLY6A== + dependencies: + core-js-pure "^3.0.0" + regenerator-runtime "^0.13.4" + "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3": version "7.6.3" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.3.tgz#935122c74c73d2240cafd32ddb5fc2a6cd35cf1f" @@ -2741,6 +2749,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.9.2": + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" + integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/runtime@^7.3.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.3.tgz#0811944f73a6c926bb2ad35e918dcc1bfab279f1" @@ -5470,6 +5485,33 @@ "@svgr/plugin-svgo" "^4.3.1" loader-utils "^1.2.3" +"@testing-library/dom@^7.17.1": + version "7.22.1" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.22.1.tgz#b66861fb7751287bda63a55f5c72ca808c63043c" + integrity sha512-bEszhvj9LcspaRz56mqGV7uc+vJTAYKCKPJcGb5X6U1qBysgTAgCexQXvKZ3BBjWu5S/TANP2NniOVsMWqKXcw== + dependencies: + "@babel/runtime" "^7.10.3" + "@types/aria-query" "^4.2.0" + aria-query "^4.2.2" + dom-accessibility-api "^0.5.0" + pretty-format "^25.5.0" + +"@testing-library/jest-dom@^5.11.3": + version "5.11.3" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.11.3.tgz#3802cb244e9ab50559a20344698a2d41f9bf11ec" + integrity sha512-vP8ABJt4+YIzu9UItbpJ6nM5zN3g9/tpLcp2DJiXyfX9gnwgcmLsa42+YiohNGEtSUTsseb6xB9HAwlgk8WdaQ== + dependencies: + "@babel/runtime" "^7.9.2" + "@types/testing-library__jest-dom" "^5.9.1" + aria-query "^4.2.2" + chalk "^3.0.0" + css "^3.0.0" + css.escape "^1.5.1" + jest-diff "^25.1.0" + jest-matcher-utils "^25.1.0" + lodash "^4.17.15" + redent "^3.0.0" + "@testing-library/react-hooks@^3.2.1": version "3.2.1" resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-3.2.1.tgz#19b6caa048ef15faa69d439c469033873ea01294" @@ -5478,6 +5520,14 @@ "@babel/runtime" "^7.5.4" "@types/testing-library__react-hooks" "^3.0.0" +"@testing-library/react@^10.4.8": + version "10.4.8" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-10.4.8.tgz#5eb730291b8fd81cdb2d8877770d060b044ae4a4" + integrity sha512-clgpFR6QHiRRcdhFfAKDhH8UXpNASyfkkANhtCsCVBnai+O+mK1rGtMES+Apc7ql5Wyxu7j8dcLiC4pV5VblHA== + dependencies: + "@babel/runtime" "^7.10.3" + "@testing-library/dom" "^7.17.1" + "@torkelo/react-select@3.0.8": version "3.0.8" resolved "https://registry.yarnpkg.com/@torkelo/react-select/-/react-select-3.0.8.tgz#04bfc877118af425f97eac2b471b66705484ee4a" @@ -5524,6 +5574,11 @@ resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== +"@types/aria-query@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" + integrity sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A== + "@types/babel-types@*", "@types/babel-types@^7.0.0": version "7.0.7" resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.7.tgz#667eb1640e8039436028055737d2b9986ee336e3" @@ -6673,6 +6728,13 @@ resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370" integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ== +"@types/testing-library__jest-dom@^5.9.1", "@types/testing-library__jest-dom@^5.9.2": + version "5.9.2" + resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.9.2.tgz#59e4771a1cf87d51e89a5cc8195cd3b647cba322" + integrity sha512-K7nUSpH/5i8i0NagTJ+uFUDRueDlnMNhJtMjMwTGPPSqyImbWC/hgKPDCKt6Phu2iMJg2kWqlax+Ucj2DKMwpA== + dependencies: + "@types/jest" "*" + "@types/testing-library__react-hooks@^3.0.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@types/testing-library__react-hooks/-/testing-library__react-hooks-3.1.0.tgz#04d174ce767fbcce3ccb5021d7f156e1b06008a9" @@ -7590,6 +7652,14 @@ argv-tools@^0.1.1: array-back "^2.0.0" find-replace "^2.0.1" +aria-query@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" + integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== + dependencies: + "@babel/runtime" "^7.10.2" + "@babel/runtime-corejs3" "^7.10.2" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -10095,6 +10165,11 @@ core-js-compat@^3.6.2: browserslist "^4.8.3" semver "7.0.0" +core-js-pure@^3.0.0: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813" + integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA== + core-js-pure@^3.0.1: version "3.3.2" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.3.2.tgz#ace92f9744ef1f6129f73ac4df4936b6df9a3cbe" @@ -10467,6 +10542,20 @@ css-what@2.1, css-what@^2.1.2: resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== +css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= + +css@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" + integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== + dependencies: + inherits "^2.0.4" + source-map "^0.6.1" + source-map-resolve "^0.6.0" + cssdb@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" @@ -11405,6 +11494,11 @@ doctypes@^1.1.0: resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" integrity sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk= +dom-accessibility-api@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.0.tgz#fddffd04e178796e241436c3f21be2f89c91afac" + integrity sha512-eCVf9n4Ni5UQAFc2+fqfMPHdtiX7DA0rLakXgNBZfXNJzEbNo3MQIYd+zdYpFBqAaGYVrkd8leNSLGPrG4ODmA== + dom-align@^1.7.0: version "1.10.2" resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.10.2.tgz#540ea1c9e20462bd11b9fc28c561dc8351ece4c6" @@ -14912,7 +15006,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -16015,7 +16109,7 @@ jest-diff@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" -jest-diff@^25.2.1: +jest-diff@^25.1.0, jest-diff@^25.2.1, jest-diff@^25.5.0: version "25.5.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9" integrity sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A== @@ -16252,6 +16346,16 @@ jest-matcher-utils@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" +jest-matcher-utils@^25.1.0: + version "25.5.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz#fbc98a12d730e5d2453d7f1ed4a4d948e34b7867" + integrity sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw== + dependencies: + chalk "^3.0.0" + jest-diff "^25.5.0" + jest-get-type "^25.2.6" + pretty-format "^25.5.0" + jest-matcher-utils@^26.0.1: version "26.0.1" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz#12e1fc386fe4f14678f4cc8dbd5ba75a58092911" @@ -22506,6 +22610,14 @@ redent@^2.0.0: indent-string "^3.0.0" strip-indent "^2.0.0" +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + reduce-flatten@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-1.0.1.tgz#258c78efd153ddf93cb561237f61184f3696e327" @@ -24166,6 +24278,14 @@ source-map-resolve@^0.5.3: source-map-url "^0.4.0" urix "^0.1.0" +source-map-resolve@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" + integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + source-map-support@^0.3.2: version "0.3.3" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.3.3.tgz#34900977d5ba3f07c7757ee72e73bb1a9b53754f"