From 4cdcca382659050e1c73c7eb9542c8fb871d10aa Mon Sep 17 00:00:00 2001 From: IswaryaS Date: Sun, 22 May 2022 18:24:06 +0530 Subject: [PATCH] Check error instance for arguments test (#2044) Co-authored-by: Iswarya Sankaran --- test/arguments.ts | 73 ++++++++++++++++++++++++++++++++++++----------- test/cancel.ts | 17 +++++++---- test/cookies.ts | 27 ++++++++++++++---- test/create.ts | 5 +++- test/error.ts | 37 ++++++++++++++++++++---- 5 files changed, 125 insertions(+), 34 deletions(-) diff --git a/test/arguments.ts b/test/arguments.ts index 96bea4a0c..73d2776de 100644 --- a/test/arguments.ts +++ b/test/arguments.ts @@ -15,6 +15,7 @@ test('`url` is required', async t => { // @ts-expect-error No argument on purpose. got(), { + instanceOf: RequestError, message: 'Missing `url` property', }, ); @@ -30,6 +31,7 @@ test('`url` should be utf-8 encoded', async t => { await t.throwsAsync( got('https://example.com/%D2%E0%EB%EB%E8%ED'), { + instanceOf: RequestError, message: 'URI malformed', }, ); @@ -38,12 +40,14 @@ test('`url` should be utf-8 encoded', async t => { test('throws if no arguments provided', async t => { // @ts-expect-error Error tests await t.throwsAsync(got(), { + instanceOf: RequestError, message: 'Missing `url` property', }); }); test('throws if the url option is missing', async t => { await t.throwsAsync(got({}), { + instanceOf: RequestError, message: 'Missing `url` property', }); }); @@ -93,17 +97,22 @@ test('throws an error when legacy URL is passed', withServer, async (t, server) await t.throwsAsync( // @ts-expect-error Error tests got(parse(`${server.url}/test`)), + { + instanceOf: RequestError, + message: 'Expected value which is `predicate returns truthy for any value`, received values of types `Object`.', + }, ); - // TODO: Assert message above. - await t.throwsAsync( got({ protocol: 'http:', hostname: 'localhost', port: server.port, } as any), - {message: 'Unexpected option: protocol'}, + { + instanceOf: RequestError, + message: 'Unexpected option: protocol', + }, ); }); @@ -163,6 +172,7 @@ test('ignores empty searchParams object', withServer, async (t, server, got) => test('throws when passing body with a non payload method', async t => { await t.throwsAsync(got('https://example.com', {body: 'asdf'}), { + instanceOf: RequestError, message: 'The `GET` method cannot be used with a body', }); }); @@ -206,6 +216,7 @@ test('throws when `options.hooks` is not an object', async t => { // @ts-expect-error Error tests got('https://example.com', {hooks: 'not object'}), { + instanceOf: RequestError, message: 'Expected value which is `Object`, received value of type `string`.', }, ); @@ -215,9 +226,11 @@ test('throws when known `options.hooks` value is not an array', async t => { await t.throwsAsync( // @ts-expect-error Error tests got('https://example.com', {hooks: {beforeRequest: {}}}), + { + instanceOf: RequestError, + message: 'Expected value which is `predicate returns truthy for any value`, received values of types `Object`.', + }, ); - - // TODO: Assert message above. }); test('throws when known `options.hooks` array item is not a function', async t => { @@ -225,6 +238,7 @@ test('throws when known `options.hooks` array item is not a function', async t = // @ts-expect-error Error tests got('https://example.com', {hooks: {beforeRequest: [{}]}}), { + instanceOf: RequestError, message: 'Expected value which is `Function`, received value of type `Object`.', }, ); @@ -235,6 +249,7 @@ test('does not allow extra keys in `options.hooks`', withServer, async (t, serve // @ts-expect-error Error tests await t.throwsAsync(got('test', {hooks: {extra: []}}), { + instanceOf: RequestError, message: 'Unexpected hook event: extra', }); }); @@ -286,9 +301,11 @@ test('throws if the `searchParams` value is invalid', async t => { // @ts-expect-error Error tests foo: [], }, - })); - - // TODO: Assert message above. + }), + { + instanceOf: RequestError, + message: 'Expected value which is `predicate returns truthy for any value`, received values of types `Array`.', + }); }); test.failing('`context` option is enumerable', withServer, async (t, server, got) => { @@ -365,20 +382,29 @@ test('throws if `options.encoding` is `null`', async t => { await t.throwsAsync(got('https://example.com', { // @ts-expect-error For testing purposes encoding: null, - }), {message: 'To get a Buffer, set `options.responseType` to `buffer` instead'}); + }), { + instanceOf: RequestError, + message: 'To get a Buffer, set `options.responseType` to `buffer` instead', + }); }); test('`url` option and input argument are mutually exclusive', async t => { await t.throwsAsync(got('https://example.com', { url: 'https://example.com', - }), {message: 'The `url` option is mutually exclusive with the `input` argument'}); + }), { + instanceOf: RequestError, + message: 'The `url` option is mutually exclusive with the `input` argument', + }); }); test('throws a helpful error when passing `followRedirects`', async t => { await t.throwsAsync(got('https://example.com', { // @ts-expect-error For testing purposes followRedirects: true, - }), {message: 'The `followRedirects` option does not exist. Use `followRedirect` instead.'}); + }), { + instanceOf: RequestError, + message: 'The `followRedirects` option does not exist. Use `followRedirect` instead.', + }); }); test('merges `searchParams` instances', t => { @@ -400,12 +426,14 @@ test('throws a helpful error when passing `auth`', async t => { // @ts-expect-error For testing purposes auth: 'username:password', }), { + instanceOf: RequestError, message: 'Parameter `auth` is deprecated. Use `username` / `password` instead.', }); }); test('throws on leading slashes', async t => { await t.throwsAsync(got('/asdf', {prefixUrl: 'https://example.com'}), { + instanceOf: RequestError, message: '`url` must not start with a slash', }); }); @@ -414,9 +442,11 @@ test('throws on invalid `dnsCache` option', async t => { await t.throwsAsync(got('https://example.com', { // @ts-expect-error Error tests dnsCache: 123, - })); - - // TODO: Assert message above. + }), + { + instanceOf: RequestError, + message: 'Expected value which is `predicate returns truthy for any value`, received values of types `number`.', + }); }); test('throws on invalid `agent` option', async t => { @@ -425,7 +455,10 @@ test('throws on invalid `agent` option', async t => { // @ts-expect-error Error tests asdf: 123, }, - }), {message: 'Unexpected agent option: asdf'}); + }), { + instanceOf: RequestError, + message: 'Unexpected agent option: asdf', + }); }); test('fallbacks to native http if `request(...)` returns undefined', withServer, async (t, server, got) => { @@ -557,6 +590,7 @@ test('throws on too large noise', t => { }, }); }, { + instanceOf: Error, message: 'The maximum acceptable retry noise is +/- 100ms, got 101', }); @@ -567,6 +601,7 @@ test('throws on too large noise', t => { }, }); }, { + instanceOf: Error, message: 'The maximum acceptable retry noise is +/- 100ms, got -101', }); @@ -577,6 +612,7 @@ test('throws on too large noise', t => { }, }); }, { + instanceOf: Error, message: 'The maximum acceptable retry noise is +/- 100ms, got Infinity', }); @@ -587,6 +623,7 @@ test('throws on too large noise', t => { }, }); }, { + instanceOf: Error, message: 'The maximum acceptable retry noise is +/- 100ms, got -Infinity', }); @@ -608,6 +645,7 @@ test('options have url even if some are invalid', async t => { })); t.is((error.options.url as URL).href, 'https://example.com/'); + t.true(error instanceof Error); }); test('options have url even if some are invalid - got.extend', async t => { @@ -623,5 +661,8 @@ test('options have url even if some are invalid - got.extend', async t => { await t.throwsAsync(instance('https://example.com', { // @ts-expect-error Testing purposes invalid: true, - })); + }), + { + instanceOf: Error, + }); }); diff --git a/test/cancel.ts b/test/cancel.ts index d87b2ed0c..c41ac0861 100644 --- a/test/cancel.ts +++ b/test/cancel.ts @@ -6,7 +6,7 @@ import delay from 'delay'; import {pEvent} from 'p-event'; import getStream from 'get-stream'; import {Handler} from 'express'; -import got, {CancelError, TimeoutError} from '../source/index.js'; +import got, {CancelError, TimeoutError, RequestError} from '../source/index.js'; import slowDataStream from './helpers/slow-data-stream.js'; import {GlobalClock} from './helpers/types.js'; import {ExtendedHttpTestServer} from './helpers/create-http-test-server.js'; @@ -180,7 +180,10 @@ test.serial('cancel immediately', withServerAndFakeTimers, async (t, server, got const gotPromise = got('abort'); gotPromise.cancel(); - await t.throwsAsync(gotPromise); + await t.throwsAsync(gotPromise, { + instanceOf: CancelError, + code: 'ERR_CANCELED', + }); await t.notThrowsAsync(promise, 'Request finished instead of aborting.'); }); @@ -230,9 +233,8 @@ test.serial('throws on incomplete (canceled) response - promise', withServerAndF ); }); -// TODO: Use `fakeTimers` here -test.serial('throws on incomplete (canceled) response - promise #2', withServer, async (t, server, got) => { - server.get('/', downloadHandler()); +test.serial('throws on incomplete (canceled) response - promise #2', withServerAndFakeTimers, async (t, server, got, clock) => { + server.get('/', downloadHandler(clock)); const promise = got(''); @@ -256,7 +258,10 @@ test.serial('throws on incomplete (canceled) response - stream', withServerAndFa stream.destroy(new Error(errorString)); }); - await t.throwsAsync(getStream(stream), {message: errorString}); + await t.throwsAsync(getStream(stream), { + instanceOf: RequestError, + message: errorString, + }); }); test('throws when canceling cached request', withServer, async (t, server, got) => { diff --git a/test/cookies.ts b/test/cookies.ts index e706830a4..fd1d8f2e9 100644 --- a/test/cookies.ts +++ b/test/cookies.ts @@ -2,7 +2,7 @@ import net from 'net'; import test from 'ava'; import toughCookie from 'tough-cookie'; import delay from 'delay'; -import got from '../source/index.js'; +import {got, RequestError} from '../source/index.js'; import withServer from './helpers/with-server.js'; test('reads a cookie', withServer, async (t, server, got) => { @@ -63,7 +63,10 @@ test('throws on invalid cookies', withServer, async (t, server, got) => { const cookieJar = new toughCookie.CookieJar(); - await t.throwsAsync(got({cookieJar}), {message: 'Cookie has domain set to a public suffix'}); + await t.throwsAsync(got({cookieJar}), { + instanceOf: RequestError, + message: 'Cookie has domain set to a public suffix', + }); }); test('does not throw on invalid cookies when options.ignoreInvalidCookies is set', withServer, async (t, server, got) => { @@ -98,7 +101,10 @@ test('catches store errors', async t => { synchronous: false, }); - await t.throwsAsync(got('https://example.com', {cookieJar}), {message: error}); + await t.throwsAsync(got('https://example.com', {cookieJar}), { + instanceOf: RequestError, + message: error, + }); }); test('overrides options.headers.cookie', withServer, async (t, server, got) => { @@ -139,7 +145,10 @@ test('no unhandled errors', async t => { }, }; - await t.throwsAsync(got(`http://127.0.0.1:${(server.address() as net.AddressInfo).port}`, options), {message}); + await t.throwsAsync(got(`http://127.0.0.1:${(server.address() as net.AddressInfo).port}`, options), { + instanceOf: RequestError, + message, + }); await delay(500); t.pass(); @@ -177,7 +186,10 @@ test('throws on invalid `options.cookieJar.setCookie`', async t => { // @ts-expect-error Error tests setCookie: 123, }, - }), {message: 'Expected value which is `Function`, received value of type `number`.'}); + }), { + instanceOf: RequestError, + message: 'Expected value which is `Function`, received value of type `number`.', + }); }); test('throws on invalid `options.cookieJar.getCookieString`', async t => { @@ -187,7 +199,10 @@ test('throws on invalid `options.cookieJar.getCookieString`', async t => { // @ts-expect-error Error tests getCookieString: 123, }, - }), {message: 'Expected value which is `Function`, received value of type `number`.'}); + }), { + instanceOf: RequestError, + message: 'Expected value which is `Function`, received value of type `number`.', + }); }); test('cookies are cleared when redirecting to a different hostname (no cookieJar)', withServer, async (t, server, got) => { diff --git a/test/create.ts b/test/create.ts index 84d810822..14cc38cc9 100644 --- a/test/create.ts +++ b/test/create.ts @@ -341,7 +341,10 @@ test('async handlers can throw', async t => { ], }); - await t.throwsAsync(instance('https://example.com'), {message}); + await t.throwsAsync(instance('https://example.com'), { + instanceOf: Error, + message, + }); }); test('setting dnsCache to true points to global cache', t => { diff --git a/test/error.ts b/test/error.ts index 10c174982..e50c658d0 100644 --- a/test/error.ts +++ b/test/error.ts @@ -47,6 +47,10 @@ test('catches dns errors', async t => { test('`options.body` form error message', async t => { // @ts-expect-error Error tests await t.throwsAsync(got.post('https://example.com', {body: Buffer.from('test'), form: ''}), + { + instanceOf: RequestError, + message: 'Expected value which is `predicate returns truthy for any value`, received values of types `string`.', + }, // {message: 'The `body`, `json` and `form` options are mutually exclusive'} ); }); @@ -71,7 +75,11 @@ test('default status message', withServer, async (t, server, got) => { response.end('body'); }); - const error = await t.throwsAsync(got('')); + const error = await t.throwsAsync(got(''), + { + instanceOf: HTTPError, + message: 'Response code 400 (Bad Request)', + }); t.is(error.response.statusCode, 400); t.is(error.response.statusMessage, 'Bad Request'); }); @@ -83,7 +91,11 @@ test('custom status message', withServer, async (t, server, got) => { response.end('body'); }); - const error = await t.throwsAsync(got('')); + const error = await t.throwsAsync(got(''), + { + instanceOf: HTTPError, + message: 'Response code 400 (Something Exploded)', + }); t.is(error.response.statusCode, 400); t.is(error.response.statusMessage, 'Something Exploded'); }); @@ -94,7 +106,11 @@ test('custom body', withServer, async (t, server, got) => { response.end('not'); }); - const error = await t.throwsAsync(got('')); + const error = await t.throwsAsync(got(''), + { + instanceOf: HTTPError, + message: 'Response code 404 (Not Found)', + }); t.is(error.response.statusCode, 404); t.is(error.response.body, 'not'); }); @@ -111,7 +127,11 @@ test('contains Got options', withServer, async (t, server, got) => { }, } as const; - const error = await t.throwsAsync(got(options)); + const error = await t.throwsAsync(got(options), + { + instanceOf: HTTPError, + message: 'Response code 404 (Not Found)', + }); t.is(error.response.statusCode, 404); t.is(error.options.context.foo, options.context.foo); }); @@ -122,7 +142,11 @@ test('empty status message is overriden by the default one', withServer, async ( response.end('body'); }); - const error = await t.throwsAsync(got('')); + const error = await t.throwsAsync(got(''), + { + instanceOf: HTTPError, + message: 'Response code 400 (Bad Request)', + }); t.is(error.response.statusCode, 400); t.is(error.response.statusMessage, http.STATUS_CODES[400]); }); @@ -193,6 +217,7 @@ test('returns a stream even if normalization fails', async t => { }) as unknown as Request; await t.throwsAsync(getStream(stream), { + instanceOf: RequestError, message: 'Expected value which is `Object`, received value of type `boolean`.', }); }); @@ -265,6 +290,7 @@ test('no uncaught parse errors', async t => { }); await t.throwsAsync(got.head(`http://localhost:${(server.address() as net.AddressInfo).port}`), { + instanceOf: RequestError, message: /^Parse Error/, }); @@ -290,6 +316,7 @@ test('no uncaught parse errors #2', async t => { }); await t.throwsAsync(got(`http://localhost:${(server.address() as net.AddressInfo).port}`), { + instanceOf: RequestError, message: /^Parse Error/, });