Task 1.1.

List up to five functions that you think are not tested sufficiently.

Note: A function may be insufficiently tested if the tests do not fully exercise different scenarios that can occur in the function. As such, programmers are not able to verify all outcomes confidently.

Note: Provide function's name and a line number per function.

      
    /**
    * Body.js
    *
    * Body interface provides common methods for Request and Response
    */
   
    import Stream, {PassThrough} from 'node:stream';
    import {types, deprecate, promisify} from 'node:util';
    import {Buffer} from 'node:buffer';
   
    import Blob from 'fetch-blob';
    import {FormData, formDataToBlob} from 'formdata-polyfill/esm.min.js';
   
    import {FetchError} from './errors/fetch-error.js';
    import {FetchBaseError} from './errors/base.js';
    import {isBlob, isURLSearchParameters} from './utils/is.js';
   
    const pipeline = promisify(Stream.pipeline);
    const INTERNALS = Symbol('Body internals');
   
    /**
    * Body mixin
    *
    * Ref: https://fetch.spec.whatwg.org/#body
    *
    * @param   Stream  body  Readable stream
    * @param   Object  opts  Response options
    * @return  Void
    */
    export default class Body {
    	constructor(body, {
    		size = 0
    	} = {}) {
    		let boundary = null;
    
    		if (body === null) {
    			// Body is undefined or null
    			body = null;
    		} else if (isURLSearchParameters(body)) {
    			// Body is a URLSearchParams
    			body = Buffer.from(body.toString());
    		} else if (body instanceof FormData) {
    			// Body is FormData
    			body = formDataToBlob(body);
    			boundary = body.type.split('=')[1];
    		} else {
    			// None of the above
    			// coerce to string then buffer
    			body = Buffer.from(String(body));
    		}
    
    		let stream = body;
    
    		if (Buffer.isBuffer(body)) {
    			stream = Stream.Readable.from(body);
    		} else if (isBlob(body)) {
    			stream = Stream.Readable.from(body.stream());
    		}
    
    		if (body instanceof Stream) {
    			body.on('error', error_ => {
    				const error = error_ instanceof FetchBaseError ?
    					error_ :
    					new FetchError(`Invalid response body while trying to fetch ${this.url}: ${error_.message}`, 'system', error_);
    				this[INTERNALS].error = error;
    			});
    		}
    	}
    
    	get body() {
    		return this[INTERNALS].stream;
    	}
    
    	get bodyUsed() {
    		return this[INTERNALS].disturbed;
    	}
    
    	/**
    	 * Decode response as ArrayBuffer
    	 *
    	 * @return  Promise
    	 */
    	async function arrayBuffer() {
    		const {buffer, byteOffset, byteLength} = await consumeBody(this);
    		return buffer.slice(byteOffset, byteOffset + byteLength);
    	}
    
    	async function formData() {
    		const ct = this.headers.get('content-type');
    
    		if (ct.startsWith('application/x-www-form-urlencoded')) {
    			const formData = new FormData();
    			const parameters = new URLSearchParams(await this.text());
    
    			for (const [name, value] of parameters) {
    				formData.append(name, value);
    			}
    
    			return formData;
    		}
    
    		const {toFormData} = await import('./utils/multipart-parser.js');
    		return toFormData(this.body, ct);
    	}
    
    	/**
    	 * Return raw response as Blob
    	 *
    	 * @return Promise
    	 */
    	async function blob() {
    		const ct = (this.headers && this.headers.get('content-type')) || (this[INTERNALS].body && this[INTERNALS].body.type) || '';
    		const buf = await this.arrayBuffer();
    		return new Blob([buf], {
    			type: ct
    		});
    	}
    
    	/**
    	 * Decode response as json
    	 *
    	 * @return  Promise
    	 */
    	async function json() {
    		const buffer = await consumeBody(this);
    		return JSON.parse(buffer.toString());
    	}
    
    	/**
    	 * Decode response as text
    	 *
    	 * @return  Promise
    	 */
    	async function text() {
    		const buffer = await consumeBody(this);
    		return new TextDecoder().decode(buffer);
    	}
    
    	/**
    	 * Decode response as buffer (non-spec api)
    	 *
    	 * @return  Promise
    	 */
    	function buffer() {
    		return consumeBody(this);
    	}
    }
    
    Body.prototype.buffer = deprecate(Body.prototype.buffer, 'Please use \'response.arrayBuffer()\' instead of \'response.buffer()\'', 'node-fetch#buffer');
    
    // In browsers, all properties are enumerable.
    Object.defineProperties(Body.prototype, {
    	body: {enumerable: true},
    	bodyUsed: {enumerable: true},
    	arrayBuffer: {enumerable: true},
    	blob: {enumerable: true},
    	json: {enumerable: true},
    	text: {enumerable: true},
    	data: {get: deprecate(() => {},
    		'data doesn\'t exist, use json(), text(), arrayBuffer(), or body instead',
    		'https://github.com/node-fetch/node-fetch/issues/1000 (response)')}
    });
    
    /**
     * Consume and convert an entire Body to a Buffer.
     *
     * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body
     *
     * @return Promise
     */
    async function consumeBody(data) {
    	if (data[INTERNALS].disturbed) {
    		throw new TypeError(`body used already for: ${data.url}`);
    	}
    
    	data[INTERNALS].disturbed = true;
    
    	if (data[INTERNALS].error) {
    		throw data[INTERNALS].error;
    	}
    
    	const {body} = data;
    
    	// Body is null
    	if (body === null) {
    		return Buffer.alloc(0);
    	}
    
    	/* c8 ignore next 3 */
    	if (!(body instanceof Stream)) {
    		return Buffer.alloc(0);
    	}
    
    	// Body is stream
    	// get ready to actually consume the body
    	const accum = [];
    	let accumBytes = 0;
    
    	try {
    		for await (const chunk of body) {
    			if (data.size > 0 && accumBytes + chunk.length > data.size) {
    				const error = new FetchError(`content size at ${data.url} over limit: ${data.size}`, 'max-size');
    				body.destroy(error);
    				throw error;
    			}
    
    			accumBytes += chunk.length;
    			accum.push(chunk);
    		}
    	} catch (error) {
    		const error_ = error instanceof FetchBaseError ? error : new FetchError(`Invalid response body while trying to fetch ${data.url}: ${error.message}`, 'system', error);
    		throw error_;
    	}
    
    	if (body.readableEnded === true || body._readableState.ended === true) {
    		try {
    			if (accum.every(c => typeof c === 'string')) {
    				return Buffer.from(accum.join(''));
    			}
    
    			return Buffer.concat(accum, accumBytes);
    		} catch (error) {
    			throw new FetchError(`Could not create Buffer from response body for ${data.url}: ${error.message}`, 'system', error);
    		}
    	} else {
    		throw new FetchError(`Premature close of server response while trying to fetch ${data.url}`);
    	}
    }
    
    /**
     * Clone body given Res/Req instance
     *
     * @param   Mixed   instance       Response or Request instance
     * @param   String  highWaterMark  highWaterMark for both PassThrough body streams
     * @return  Mixed
     */
    function clone(instance, highWaterMark) {
    	let p1;
    	let p2;
    	let {body} = instance[INTERNALS];
    
    	// Don't allow cloning a used body
    	if (instance.bodyUsed) {
    		throw new Error('cannot clone body after it is used');
    	}
    
    	// Check that body is a stream and not form-data object
    	// note: we can't clone the form-data object without having it as a dependency
    	if ((body instanceof Stream) && (typeof body.getBoundary !== 'function')) {
    		// Tee instance body
    		p1 = new PassThrough({highWaterMark});
    		p2 = new PassThrough({highWaterMark});
    		body.pipe(p1);
    		body.pipe(p2);
    		// Set instance body to teed body and return the other teed body
    		instance[INTERNALS].stream = p1;
    		body = p2;
    	}
    
    	return body;
    };
    
    const getNonSpecFormDataBoundary = deprecate(
    	body => body.getBoundary(),
    	'form-data doesn\'t follow the spec and requires special treatment. Use alternative package',
    	'https://github.com/node-fetch/node-fetch/issues/1167'
    );
    
    /**
     * Performs the operation "extract a `Content-Type` value from |object|" as
     * specified in the specification:
     * https://fetch.spec.whatwg.org/#concept-bodyinit-extract
     *
     * This function assumes that instance.body is present.
     *
     * @param {any} body Any options.body input
     * @returns {string | null}
     */
    function extractContentType(body, request) {
    	// Body is null or undefined
    	if (body === null) {
    		return null;
    	}
    
    	// Body is string
    	if (typeof body === 'string') {
    		return 'text/plain;charset=UTF-8';
    	}
    
    	// Body is blob
    	if (isBlob(body)) {
    		return body.type || null;
    	}
    
    	// Body is a Buffer (Buffer, ArrayBuffer or ArrayBufferView)
    	if (Buffer.isBuffer(body) || types.isAnyArrayBuffer(body) || ArrayBuffer.isView(body)) {
    		return null;
    	}
    
    	// Body is stream - can't really do much about this
    	if (body instanceof Stream) {
    		return null;
    	}
    
    	// Body constructor defaults other things to string
    	return 'text/plain;charset=UTF-8';
    };
    
    /**
     * The Fetch Standard treats this as if "total bytes" is a property on the body.
     * For us, we have to explicitly get it with a function.
    *
     * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes
     *
     * @param {any} obj.body Body object from the Body instance.
     * @returns {number | null}
     */
    function getTotalBytes(request) {
    	const {body} = request[INTERNALS];
    
    	// Body is null or undefined
    	if (body === null) {
    		return 0;
    	}
    
    	// Body is Blob
    	if (isBlob(body)) {
    		return body.size;
    	}
    
    	// Body is Buffer
    	if (Buffer.isBuffer(body)) {
    		return body.length;
    	}
    
    	// Detect form data input from form-data module
    	if (body && typeof body.getLengthSync === 'function') {
    		return body.hasKnownLength && body.hasKnownLength() ? body.getLengthSync() : null;
    	}
    
    	// Body is stream
    	return null;
    };
    
    /**
     * Write a Body to a Node.js WritableStream (e.g. http.Request) object.
     *
    * @param {Stream.Writable} dest The stream to write to.
     * @param obj.body Body object from the Body instance.
     * @returns {Promise}
     */
    async function writeToStream(dest, {body}) {
    	if (body === null) {
    		// Body is null
    		dest.end();
    	} else {
    		// Body is stream
    		await pipeline(body, dest);
    	}
    };