Migrated tests to jest
Used jest-codemods to migrate, will have to pass everything by hand before we can merge.
This commit is contained in:
6
test3/groupBy/groupBy.js
Normal file
6
test3/groupBy/groupBy.js
Normal file
@ -0,0 +1,6 @@
|
||||
const groupBy = (arr, fn) =>
|
||||
arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val, i) => {
|
||||
acc[val] = (acc[val] || []).concat(arr[i]);
|
||||
return acc;
|
||||
}, {});
|
||||
module.exports = groupBy;
|
||||
10
test3/groupBy/groupBy.test.js
Normal file
10
test3/groupBy/groupBy.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
const expect = require('expect');
|
||||
const groupBy = require('./groupBy.js');
|
||||
|
||||
test('Testing groupBy', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof groupBy === 'function').toBeTruthy();
|
||||
expect(groupBy([6.1, 4.2, 6.3], Math.floor)).toEqual({4: [4.2], 6: [6.1, 6.3]});
|
||||
expect(groupBy(['one', 'two', 'three'], 'length')).toEqual({3: ['one', 'two'], 5: ['three']});
|
||||
});
|
||||
2
test3/hammingDistance/hammingDistance.js
Normal file
2
test3/hammingDistance/hammingDistance.js
Normal file
@ -0,0 +1,2 @@
|
||||
const hammingDistance = (num1, num2) => ((num1 ^ num2).toString(2).match(/1/g) || '').length;
|
||||
module.exports = hammingDistance;
|
||||
9
test3/hammingDistance/hammingDistance.test.js
Normal file
9
test3/hammingDistance/hammingDistance.test.js
Normal file
@ -0,0 +1,9 @@
|
||||
const expect = require('expect');
|
||||
const hammingDistance = require('./hammingDistance.js');
|
||||
|
||||
test('Testing hammingDistance', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof hammingDistance === 'function').toBeTruthy();
|
||||
expect(hammingDistance(2, 3)).toBe(1);
|
||||
});
|
||||
2
test3/hasClass/hasClass.js
Normal file
2
test3/hasClass/hasClass.js
Normal file
@ -0,0 +1,2 @@
|
||||
const hasClass = (el, className) => el.classList.contains(className);
|
||||
module.exports = hasClass;
|
||||
8
test3/hasClass/hasClass.test.js
Normal file
8
test3/hasClass/hasClass.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const hasClass = require('./hasClass.js');
|
||||
|
||||
test('Testing hasClass', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof hasClass === 'function').toBeTruthy();
|
||||
});
|
||||
3
test3/hasFlags/hasFlags.js
Normal file
3
test3/hasFlags/hasFlags.js
Normal file
@ -0,0 +1,3 @@
|
||||
const hasFlags = (...flags) =>
|
||||
flags.every(flag => process.argv.includes(/^-{1,2}/.test(flag) ? flag : '--' + flag));
|
||||
module.exports = hasFlags;
|
||||
8
test3/hasFlags/hasFlags.test.js
Normal file
8
test3/hasFlags/hasFlags.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const hasFlags = require('./hasFlags.js');
|
||||
|
||||
test('Testing hasFlags', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof hasFlags === 'function').toBeTruthy();
|
||||
});
|
||||
9
test3/hashBrowser/hashBrowser.js
Normal file
9
test3/hashBrowser/hashBrowser.js
Normal file
@ -0,0 +1,9 @@
|
||||
const hashBrowser = val =>
|
||||
crypto.subtle.digest('SHA-256', new TextEncoder('utf-8').encode(val)).then(h => {
|
||||
let hexes = [],
|
||||
view = new DataView(h);
|
||||
for (let i = 0; i < view.byteLength; i += 4)
|
||||
hexes.push(('00000000' + view.getUint32(i).toString(16)).slice(-8));
|
||||
return hexes.join('');
|
||||
});
|
||||
module.exports = hashBrowser;
|
||||
8
test3/hashBrowser/hashBrowser.test.js
Normal file
8
test3/hashBrowser/hashBrowser.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const hashBrowser = require('./hashBrowser.js');
|
||||
|
||||
test('Testing hashBrowser', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof hashBrowser === 'function').toBeTruthy();
|
||||
});
|
||||
15
test3/hashNode/hashNode.js
Normal file
15
test3/hashNode/hashNode.js
Normal file
@ -0,0 +1,15 @@
|
||||
const crypto = require('crypto');
|
||||
const hashNode = val =>
|
||||
new Promise(resolve =>
|
||||
setTimeout(
|
||||
() =>
|
||||
resolve(
|
||||
crypto
|
||||
.createHash('sha256')
|
||||
.update(val)
|
||||
.digest('hex')
|
||||
),
|
||||
0
|
||||
)
|
||||
);
|
||||
module.exports = hashNode;
|
||||
9
test3/hashNode/hashNode.test.js
Normal file
9
test3/hashNode/hashNode.test.js
Normal file
@ -0,0 +1,9 @@
|
||||
const expect = require('expect');
|
||||
const hashNode = require('./hashNode.js');
|
||||
|
||||
test('Testing hashNode', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof hashNode === 'function').toBeTruthy();
|
||||
hashNode(JSON.stringify({ a: 'a', b: [1, 2, 3, 4], foo: { c: 'bar' } })).then(v => expect(v).toBe('04aa106279f5977f59f9067fa9712afc4aedc6f5862a8defc34552d8c7206393'));
|
||||
});
|
||||
2
test3/head/head.js
Normal file
2
test3/head/head.js
Normal file
@ -0,0 +1,2 @@
|
||||
const head = arr => arr[0];
|
||||
module.exports = head;
|
||||
20
test3/head/head.test.js
Normal file
20
test3/head/head.test.js
Normal file
@ -0,0 +1,20 @@
|
||||
const expect = require('expect');
|
||||
const head = require('./head.js');
|
||||
|
||||
test('Testing head', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof head === 'function').toBeTruthy();
|
||||
expect(head({ a: 1234}) === undefined).toBeTruthy();
|
||||
expect(head([1, 2, 3])).toBe(1);
|
||||
expect(head({ 0: false})).toBe(false);
|
||||
expect(head('String')).toBe('S');
|
||||
expect(() => head(null)).toThrow();
|
||||
expect(() => head(undefined)).toThrow();
|
||||
expect(() => head()).toThrow();
|
||||
|
||||
let start = new Date().getTime();
|
||||
head([1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 1122, 32124, 23232]);
|
||||
let end = new Date().getTime();
|
||||
expect((end - start) < 2000).toBeTruthy();
|
||||
});
|
||||
20
test3/hexToRGB/hexToRGB.js
Normal file
20
test3/hexToRGB/hexToRGB.js
Normal file
@ -0,0 +1,20 @@
|
||||
const hexToRGB = hex => {
|
||||
let alpha = false,
|
||||
h = hex.slice(hex.startsWith('#') ? 1 : 0);
|
||||
if (h.length === 3) h = [...h].map(x => x + x).join('');
|
||||
else if (h.length === 8) alpha = true;
|
||||
h = parseInt(h, 16);
|
||||
return (
|
||||
'rgb' +
|
||||
(alpha ? 'a' : '') +
|
||||
'(' +
|
||||
(h >>> (alpha ? 24 : 16)) +
|
||||
', ' +
|
||||
((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) +
|
||||
', ' +
|
||||
((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) +
|
||||
(alpha ? `, ${h & 0x000000ff}` : '') +
|
||||
')'
|
||||
);
|
||||
};
|
||||
module.exports = hexToRGB;
|
||||
11
test3/hexToRGB/hexToRGB.test.js
Normal file
11
test3/hexToRGB/hexToRGB.test.js
Normal file
@ -0,0 +1,11 @@
|
||||
const expect = require('expect');
|
||||
const hexToRGB = require('./hexToRGB.js');
|
||||
|
||||
test('Testing hexToRGB', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof hexToRGB === 'function').toBeTruthy();
|
||||
expect(hexToRGB('#27ae60ff')).toBe('rgba(39, 174, 96, 255)');
|
||||
expect(hexToRGB('27ae60')).toBe('rgb(39, 174, 96)');
|
||||
expect(hexToRGB('#fff')).toBe('rgb(255, 255, 255)');
|
||||
});
|
||||
2
test3/hide/hide.js
Normal file
2
test3/hide/hide.js
Normal file
@ -0,0 +1,2 @@
|
||||
const hide = (...el) => [...el].forEach(e => (e.style.display = 'none'));
|
||||
module.exports = hide;
|
||||
8
test3/hide/hide.test.js
Normal file
8
test3/hide/hide.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const hide = require('./hide.js');
|
||||
|
||||
test('Testing hide', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof hide === 'function').toBeTruthy();
|
||||
});
|
||||
11
test3/howManyTimes/howManyTimes.js
Normal file
11
test3/howManyTimes/howManyTimes.js
Normal file
@ -0,0 +1,11 @@
|
||||
const howManyTimes = (num, divisor) => {
|
||||
if (divisor === 1 || divisor === -1) return Infinity;
|
||||
if (divisor === 0) return 0;
|
||||
let i = 0;
|
||||
while (Number.isInteger(num / divisor)) {
|
||||
i++;
|
||||
num = num / divisor;
|
||||
}
|
||||
return i;
|
||||
};
|
||||
module.exports = howManyTimes;
|
||||
8
test3/howManyTimes/howManyTimes.test.js
Normal file
8
test3/howManyTimes/howManyTimes.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const howManyTimes = require('./howManyTimes.js');
|
||||
|
||||
test('Testing howManyTimes', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof howManyTimes === 'function').toBeTruthy();
|
||||
});
|
||||
8
test3/httpDelete/httpDelete.js
Normal file
8
test3/httpDelete/httpDelete.js
Normal file
@ -0,0 +1,8 @@
|
||||
const httpDelete = (url, callback, err = console.error) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open("DELETE", url, true);
|
||||
request.onload = () => callback(request);
|
||||
request.onerror = () => err(request);
|
||||
request.send();
|
||||
};
|
||||
module.exports = httpDelete;
|
||||
8
test3/httpDelete/httpDelete.test.js
Normal file
8
test3/httpDelete/httpDelete.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const httpDelete = require('./httpDelete.js');
|
||||
|
||||
test('Testing httpDelete', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof httpDelete === 'function').toBeTruthy();
|
||||
});
|
||||
8
test3/httpGet/httpGet.js
Normal file
8
test3/httpGet/httpGet.js
Normal file
@ -0,0 +1,8 @@
|
||||
const httpGet = (url, callback, err = console.error) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', url, true);
|
||||
request.onload = () => callback(request.responseText);
|
||||
request.onerror = () => err(request);
|
||||
request.send();
|
||||
};
|
||||
module.exports = httpGet;
|
||||
632
test3/httpGet/httpGet.test.js
Normal file
632
test3/httpGet/httpGet.test.js
Normal file
@ -0,0 +1,632 @@
|
||||
const expect = require("expect");
|
||||
const httpGet = (url, callback, err = console.error) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', url, true);
|
||||
request.onload = () => callback(request.responseText);
|
||||
request.onerror = () => err(request);
|
||||
request.send();
|
||||
};
|
||||
|
||||
test('Testing httpGet', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof httpGet === 'function').toBeTruthy();
|
||||
httpGet('https://jsonplaceholder.typicode.com/posts/1', response => {
|
||||
expect(JSON.parse(response)).toEqual({
|
||||
userId: 1,
|
||||
id: 1,
|
||||
title:
|
||||
'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
|
||||
body:
|
||||
'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto',
|
||||
});
|
||||
});
|
||||
});
|
||||
// Custom implementation of XMLHttpRequest for the requirements of this snippet.
|
||||
// Based on https://github.com/driverdan/node-XMLHttpRequest
|
||||
var Url = require("url");
|
||||
var spawn = require("child_process").spawn;
|
||||
var fs = require("fs");
|
||||
XMLHttpRequest = function() {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Private variables
|
||||
*/
|
||||
var self = this;
|
||||
var http = require("http");
|
||||
var https = require("https");
|
||||
|
||||
// Holds http.js objects
|
||||
var request;
|
||||
var response;
|
||||
|
||||
// Request settings
|
||||
var settings = {};
|
||||
|
||||
// Disable header blacklist.
|
||||
// Not part of XHR specs.
|
||||
var disableHeaderCheck = false;
|
||||
|
||||
// Set some default headers
|
||||
var defaultHeaders = {
|
||||
"User-Agent": "node-XMLHttpRequest",
|
||||
"Accept": "*/*",
|
||||
};
|
||||
|
||||
var headers = {};
|
||||
var headersCase = {};
|
||||
|
||||
// These headers are not user setable.
|
||||
// The following are allowed but banned in the spec:
|
||||
// * user-agent
|
||||
var forbiddenRequestHeaders = [
|
||||
"accept-charset",
|
||||
"accept-encoding",
|
||||
"access-control-request-headers",
|
||||
"access-control-request-method",
|
||||
"connection",
|
||||
"content-length",
|
||||
"content-transfer-encoding",
|
||||
"cookie",
|
||||
"cookie2",
|
||||
"date",
|
||||
"expect",
|
||||
"host",
|
||||
"keep-alive",
|
||||
"origin",
|
||||
"referer",
|
||||
"te",
|
||||
"trailer",
|
||||
"transfer-encoding",
|
||||
"upgrade",
|
||||
"via"
|
||||
];
|
||||
|
||||
// These request methods are not allowed
|
||||
var forbiddenRequestMethods = [
|
||||
"TRACE",
|
||||
"TRACK",
|
||||
"CONNECT"
|
||||
];
|
||||
|
||||
// Send flag
|
||||
var sendFlag = false;
|
||||
// Error flag, used when errors occur or abort is called
|
||||
var errorFlag = false;
|
||||
|
||||
// Event listeners
|
||||
var listeners = {};
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
this.UNSENT = 0;
|
||||
this.OPENED = 1;
|
||||
this.HEADERS_RECEIVED = 2;
|
||||
this.LOADING = 3;
|
||||
this.DONE = 4;
|
||||
|
||||
/**
|
||||
* Public vars
|
||||
*/
|
||||
|
||||
// Current state
|
||||
this.readyState = this.UNSENT;
|
||||
|
||||
// default ready state change handler in case one is not set or is set late
|
||||
this.onreadystatechange = null;
|
||||
|
||||
// Result & response
|
||||
this.responseText = "";
|
||||
this.responseXML = "";
|
||||
this.status = null;
|
||||
this.statusText = null;
|
||||
|
||||
// Whether cross-site Access-Control requests should be made using
|
||||
// credentials such as cookies or authorization headers
|
||||
this.withCredentials = false;
|
||||
|
||||
/**
|
||||
* Private methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if the specified header is allowed.
|
||||
*
|
||||
* @param string header Header to validate
|
||||
* @return boolean False if not allowed, otherwise true
|
||||
*/
|
||||
var isAllowedHttpHeader = function(header) {
|
||||
return disableHeaderCheck || (header && forbiddenRequestHeaders.indexOf(header.toLowerCase()) === -1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the specified method is allowed.
|
||||
*
|
||||
* @param string method Request method to validate
|
||||
* @return boolean False if not allowed, otherwise true
|
||||
*/
|
||||
var isAllowedHttpMethod = function(method) {
|
||||
return (method && forbiddenRequestMethods.indexOf(method) === -1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Public methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Open the connection. Currently supports local server requests.
|
||||
*
|
||||
* @param string method Connection method (eg GET, POST)
|
||||
* @param string url URL for the connection.
|
||||
* @param boolean async Asynchronous connection. Default is true.
|
||||
* @param string user Username for basic authentication (optional)
|
||||
* @param string password Password for basic authentication (optional)
|
||||
*/
|
||||
this.open = function(method, url, async, user, password) {
|
||||
this.abort();
|
||||
errorFlag = false;
|
||||
|
||||
// Check for valid request method
|
||||
if (!isAllowedHttpMethod(method)) {
|
||||
throw new Error("SecurityError: Request method not allowed");
|
||||
}
|
||||
|
||||
settings = {
|
||||
"method": method,
|
||||
"url": url.toString(),
|
||||
"async": (typeof async !== "boolean" ? true : async),
|
||||
"user": user || null,
|
||||
"password": password || null
|
||||
};
|
||||
|
||||
setState(this.OPENED);
|
||||
};
|
||||
|
||||
/**
|
||||
* Disables or enables isAllowedHttpHeader() check the request. Enabled by default.
|
||||
* This does not conform to the W3C spec.
|
||||
*
|
||||
* @param boolean state Enable or disable header checking.
|
||||
*/
|
||||
this.setDisableHeaderCheck = function(state) {
|
||||
disableHeaderCheck = state;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a header for the request or appends the value if one is already set.
|
||||
*
|
||||
* @param string header Header name
|
||||
* @param string value Header value
|
||||
*/
|
||||
this.setRequestHeader = function(header, value) {
|
||||
if (this.readyState !== this.OPENED) {
|
||||
throw new Error("INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN");
|
||||
}
|
||||
if (!isAllowedHttpHeader(header)) {
|
||||
console.warn("Refused to set unsafe header \"" + header + "\"");
|
||||
return;
|
||||
}
|
||||
if (sendFlag) {
|
||||
throw new Error("INVALID_STATE_ERR: send flag is true");
|
||||
}
|
||||
header = headersCase[header.toLowerCase()] || header;
|
||||
headersCase[header.toLowerCase()] = header;
|
||||
headers[header] = headers[header] ? headers[header] + ', ' + value : value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a header from the server response.
|
||||
*
|
||||
* @param string header Name of header to get.
|
||||
* @return string Text of the header or null if it doesn't exist.
|
||||
*/
|
||||
this.getResponseHeader = function(header) {
|
||||
if (typeof header === "string"
|
||||
&& this.readyState > this.OPENED
|
||||
&& response
|
||||
&& response.headers
|
||||
&& response.headers[header.toLowerCase()]
|
||||
&& !errorFlag
|
||||
) {
|
||||
return response.headers[header.toLowerCase()];
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets all the response headers.
|
||||
*
|
||||
* @return string A string with all response headers separated by CR+LF
|
||||
*/
|
||||
this.getAllResponseHeaders = function() {
|
||||
if (this.readyState < this.HEADERS_RECEIVED || errorFlag) {
|
||||
return "";
|
||||
}
|
||||
var result = "";
|
||||
|
||||
for (var i in response.headers) {
|
||||
// Cookie headers are excluded
|
||||
if (i !== "set-cookie" && i !== "set-cookie2") {
|
||||
result += i + ": " + response.headers[i] + "\r\n";
|
||||
}
|
||||
}
|
||||
return result.substr(0, result.length - 2);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a request header
|
||||
*
|
||||
* @param string name Name of header to get
|
||||
* @return string Returns the request header or empty string if not set
|
||||
*/
|
||||
this.getRequestHeader = function(name) {
|
||||
if (typeof name === "string" && headersCase[name.toLowerCase()]) {
|
||||
return headers[headersCase[name.toLowerCase()]];
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends the request to the server.
|
||||
*
|
||||
* @param string data Optional data to send as request body.
|
||||
*/
|
||||
this.send = function(data) {
|
||||
if (this.readyState !== this.OPENED) {
|
||||
throw new Error("INVALID_STATE_ERR: connection must be opened before send() is called");
|
||||
}
|
||||
|
||||
if (sendFlag) {
|
||||
throw new Error("INVALID_STATE_ERR: send has already been called");
|
||||
}
|
||||
|
||||
var ssl = false, local = false;
|
||||
var url = Url.parse(settings.url);
|
||||
var host;
|
||||
// Determine the server
|
||||
switch (url.protocol) {
|
||||
case "https:":
|
||||
ssl = true;
|
||||
// SSL & non-SSL both need host, no break here.
|
||||
case "http:":
|
||||
host = url.hostname;
|
||||
break;
|
||||
|
||||
case "file:":
|
||||
local = true;
|
||||
break;
|
||||
|
||||
case undefined:
|
||||
case null:
|
||||
case "":
|
||||
host = "localhost";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Protocol not supported.");
|
||||
}
|
||||
|
||||
// Load files off the local filesystem (file://)
|
||||
if (local) {
|
||||
if (settings.method !== "GET") {
|
||||
throw new Error("XMLHttpRequest: Only GET method is supported");
|
||||
}
|
||||
|
||||
if (settings.async) {
|
||||
fs.readFile(url.pathname, "utf8", function(error, data) {
|
||||
if (error) {
|
||||
self.handleError(error);
|
||||
} else {
|
||||
self.status = 200;
|
||||
self.responseText = data;
|
||||
setState(self.DONE);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
this.responseText = fs.readFileSync(url.pathname, "utf8");
|
||||
this.status = 200;
|
||||
setState(self.DONE);
|
||||
} catch(e) {
|
||||
this.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Default to port 80. If accessing localhost on another port be sure
|
||||
// to use http://localhost:port/path
|
||||
var port = url.port || (ssl ? 443 : 80);
|
||||
// Add query string if one is used
|
||||
var uri = url.pathname + (url.search ? url.search : "");
|
||||
|
||||
// Set the defaults if they haven't been set
|
||||
for (var name in defaultHeaders) {
|
||||
if (!headersCase[name.toLowerCase()]) {
|
||||
headers[name] = defaultHeaders[name];
|
||||
}
|
||||
}
|
||||
|
||||
// Set the Host header or the server may reject the request
|
||||
headers.Host = host;
|
||||
if (!((ssl && port === 443) || port === 80)) {
|
||||
headers.Host += ":" + url.port;
|
||||
}
|
||||
|
||||
// Set Basic Auth if necessary
|
||||
if (settings.user) {
|
||||
if (typeof settings.password === "undefined") {
|
||||
settings.password = "";
|
||||
}
|
||||
var authBuf = new Buffer(settings.user + ":" + settings.password);
|
||||
headers.Authorization = "Basic " + authBuf.toString("base64");
|
||||
}
|
||||
|
||||
// Set content length header
|
||||
if (settings.method === "GET" || settings.method === "HEAD") {
|
||||
data = null;
|
||||
} else if (data) {
|
||||
headers["Content-Length"] = Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data);
|
||||
|
||||
if (!headers["Content-Type"]) {
|
||||
headers["Content-Type"] = "text/plain;charset=UTF-8";
|
||||
}
|
||||
} else if (settings.method === "POST") {
|
||||
// For a post with no data set Content-Length: 0.
|
||||
// This is required by buggy servers that don't meet the specs.
|
||||
headers["Content-Length"] = 0;
|
||||
}
|
||||
|
||||
var options = {
|
||||
host: host,
|
||||
port: port,
|
||||
path: uri,
|
||||
method: settings.method,
|
||||
headers: headers,
|
||||
agent: false,
|
||||
withCredentials: self.withCredentials
|
||||
};
|
||||
|
||||
// Reset error flag
|
||||
errorFlag = false;
|
||||
|
||||
// Handle async requests
|
||||
if (settings.async) {
|
||||
// Use the proper protocol
|
||||
var doRequest = ssl ? https.request : http.request;
|
||||
|
||||
// Request is being sent, set send flag
|
||||
sendFlag = true;
|
||||
|
||||
// As per spec, this is called here for historical reasons.
|
||||
self.dispatchEvent("readystatechange");
|
||||
|
||||
// Handler for the response
|
||||
var responseHandler = function responseHandler(resp) {
|
||||
// Set response var to the response we got back
|
||||
// This is so it remains accessable outside this scope
|
||||
response = resp;
|
||||
// Check for redirect
|
||||
// @TODO Prevent looped redirects
|
||||
if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {
|
||||
// Change URL to the redirect location
|
||||
settings.url = response.headers.location;
|
||||
var url = Url.parse(settings.url);
|
||||
// Set host var in case it's used later
|
||||
host = url.hostname;
|
||||
// Options for the new request
|
||||
var newOptions = {
|
||||
hostname: url.hostname,
|
||||
port: url.port,
|
||||
path: url.path,
|
||||
method: response.statusCode === 303 ? "GET" : settings.method,
|
||||
headers: headers,
|
||||
withCredentials: self.withCredentials
|
||||
};
|
||||
|
||||
// Issue the new request
|
||||
request = doRequest(newOptions, responseHandler).on("error", errorHandler);
|
||||
request.end();
|
||||
// @TODO Check if an XHR event needs to be fired here
|
||||
return;
|
||||
}
|
||||
|
||||
response.setEncoding("utf8");
|
||||
|
||||
setState(self.HEADERS_RECEIVED);
|
||||
self.status = response.statusCode;
|
||||
|
||||
response.on("data", function(chunk) {
|
||||
// Make sure there's some data
|
||||
if (chunk) {
|
||||
self.responseText += chunk;
|
||||
}
|
||||
// Don't emit state changes if the connection has been aborted.
|
||||
if (sendFlag) {
|
||||
setState(self.LOADING);
|
||||
}
|
||||
});
|
||||
|
||||
response.on("end", function() {
|
||||
if (sendFlag) {
|
||||
// Discard the end event if the connection has been aborted
|
||||
setState(self.DONE);
|
||||
sendFlag = false;
|
||||
}
|
||||
});
|
||||
|
||||
response.on("error", function(error) {
|
||||
self.handleError(error);
|
||||
});
|
||||
};
|
||||
|
||||
// Error handler for the request
|
||||
var errorHandler = function errorHandler(error) {
|
||||
self.handleError(error);
|
||||
};
|
||||
|
||||
// Create the request
|
||||
request = doRequest(options, responseHandler).on("error", errorHandler);
|
||||
|
||||
// Node 0.4 and later won't accept empty data. Make sure it's needed.
|
||||
if (data) {
|
||||
request.write(data);
|
||||
}
|
||||
|
||||
request.end();
|
||||
|
||||
self.dispatchEvent("loadstart");
|
||||
} else { // Synchronous
|
||||
// Create a temporary file for communication with the other Node process
|
||||
var contentFile = ".node-xmlhttprequest-content-" + process.pid;
|
||||
var syncFile = ".node-xmlhttprequest-sync-" + process.pid;
|
||||
fs.writeFileSync(syncFile, "", "utf8");
|
||||
// The async request the other Node process executes
|
||||
var execString = "var http = require('http'), https = require('https'), fs = require('fs');"
|
||||
+ "var doRequest = http" + (ssl ? "s" : "") + ".request;"
|
||||
+ "var options = " + JSON.stringify(options) + ";"
|
||||
+ "var responseText = '';"
|
||||
+ "var req = doRequest(options, function(response) {"
|
||||
+ "response.setEncoding('utf8');"
|
||||
+ "response.on('data', function(chunk) {"
|
||||
+ " responseText += chunk;"
|
||||
+ "});"
|
||||
+ "response.on('end', function() {"
|
||||
+ "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText}}), 'utf8');"
|
||||
+ "fs.unlinkSync('" + syncFile + "');"
|
||||
+ "});"
|
||||
+ "response.on('error', function(error) {"
|
||||
+ "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');"
|
||||
+ "fs.unlinkSync('" + syncFile + "');"
|
||||
+ "});"
|
||||
+ "}).on('error', function(error) {"
|
||||
+ "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');"
|
||||
+ "fs.unlinkSync('" + syncFile + "');"
|
||||
+ "});"
|
||||
+ (data ? "req.write('" + JSON.stringify(data).slice(1,-1).replace(/'/g, "\\'") + "');":"")
|
||||
+ "req.end();";
|
||||
// Start the other Node Process, executing this string
|
||||
var syncProc = spawn(process.argv[0], ["-e", execString]);
|
||||
while(fs.existsSync(syncFile)) {
|
||||
// Wait while the sync file is empty
|
||||
}
|
||||
var resp = JSON.parse(fs.readFileSync(contentFile, 'utf8'));
|
||||
// Kill the child process once the file has data
|
||||
syncProc.stdin.end();
|
||||
// Remove the temporary file
|
||||
fs.unlinkSync(contentFile);
|
||||
|
||||
if (resp.err) {
|
||||
self.handleError(resp.err);
|
||||
} else {
|
||||
response = resp.data;
|
||||
self.status = resp.data.statusCode;
|
||||
self.responseText = resp.data.text;
|
||||
setState(self.DONE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when an error is encountered to deal with it.
|
||||
*/
|
||||
this.handleError = function(error) {
|
||||
this.status = 0;
|
||||
this.statusText = error;
|
||||
this.responseText = error.stack;
|
||||
errorFlag = true;
|
||||
setState(this.DONE);
|
||||
this.dispatchEvent('error');
|
||||
};
|
||||
|
||||
/**
|
||||
* Aborts a request.
|
||||
*/
|
||||
this.abort = function() {
|
||||
if (request) {
|
||||
request.abort();
|
||||
request = null;
|
||||
}
|
||||
|
||||
headers = defaultHeaders;
|
||||
this.status = 0;
|
||||
this.responseText = "";
|
||||
this.responseXML = "";
|
||||
|
||||
errorFlag = true;
|
||||
|
||||
if (this.readyState !== this.UNSENT
|
||||
&& (this.readyState !== this.OPENED || sendFlag)
|
||||
&& this.readyState !== this.DONE) {
|
||||
sendFlag = false;
|
||||
setState(this.DONE);
|
||||
}
|
||||
this.readyState = this.UNSENT;
|
||||
this.dispatchEvent('abort');
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an event listener. Preferred method of binding to events.
|
||||
*/
|
||||
this.addEventListener = function(event, callback) {
|
||||
if (!(event in listeners)) {
|
||||
listeners[event] = [];
|
||||
}
|
||||
// Currently allows duplicate callbacks. Should it?
|
||||
listeners[event].push(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove an event callback that has already been bound.
|
||||
* Only works on the matching funciton, cannot be a copy.
|
||||
*/
|
||||
this.removeEventListener = function(event, callback) {
|
||||
if (event in listeners) {
|
||||
// Filter will return a new array with the callback removed
|
||||
listeners[event] = listeners[event].filter(function(ev) {
|
||||
return ev !== callback;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatch any events, including both "on" methods and events attached using addEventListener.
|
||||
*/
|
||||
this.dispatchEvent = function(event) {
|
||||
if (typeof self["on" + event] === "function") {
|
||||
self["on" + event]();
|
||||
}
|
||||
if (event in listeners) {
|
||||
for (var i = 0, len = listeners[event].length; i < len; i++) {
|
||||
listeners[event][i].call(self);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Changes readyState and calls onreadystatechange.
|
||||
*
|
||||
* @param int state New state
|
||||
*/
|
||||
var setState = function(state) {
|
||||
if (state == self.LOADING || self.readyState !== state) {
|
||||
self.readyState = state;
|
||||
|
||||
if (settings.async || self.readyState < self.OPENED || self.readyState === self.DONE) {
|
||||
self.dispatchEvent("readystatechange");
|
||||
}
|
||||
|
||||
if (self.readyState === self.DONE && !errorFlag) {
|
||||
self.dispatchEvent("load");
|
||||
// @TODO figure out InspectorInstrumentation::didLoadXHR(cookie)
|
||||
self.dispatchEvent("loadend");
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
9
test3/httpPost/httpPost.js
Normal file
9
test3/httpPost/httpPost.js
Normal file
@ -0,0 +1,9 @@
|
||||
const httpPost = (url, data, callback, err = console.error) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('POST', url, true);
|
||||
request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
|
||||
request.onload = () => callback(request.responseText);
|
||||
request.onerror = () => err(request);
|
||||
request.send(data);
|
||||
};
|
||||
module.exports = httpPost;
|
||||
631
test3/httpPost/httpPost.test.js
Normal file
631
test3/httpPost/httpPost.test.js
Normal file
@ -0,0 +1,631 @@
|
||||
const expect = require("expect");
|
||||
const httpPost = (url, data, callback, err = console.error) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('POST', url, true);
|
||||
request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
|
||||
request.onload = () => callback(request.responseText);
|
||||
request.onerror = () => err(request);
|
||||
request.send(data);
|
||||
};
|
||||
test('Testing httpPost', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof httpPost === 'function').toBeTruthy();
|
||||
const data = {
|
||||
title: 'foo',
|
||||
body: 'bar',
|
||||
userId: 1
|
||||
};
|
||||
httpPost('https://jsonplaceholder.typicode.com/posts', JSON.stringify(data), response => {
|
||||
expect(JSON.parse(response).id).toEqual(101);
|
||||
});
|
||||
});
|
||||
|
||||
// Custom implementation of XMLHttpRequest for the requirements of this snippet.
|
||||
// Based on https://github.com/driverdan/node-XMLHttpRequest
|
||||
var Url = require("url");
|
||||
var spawn = require("child_process").spawn;
|
||||
var fs = require("fs");
|
||||
XMLHttpRequest = function() {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Private variables
|
||||
*/
|
||||
var self = this;
|
||||
var http = require("http");
|
||||
var https = require("https");
|
||||
|
||||
// Holds http.js objects
|
||||
var request;
|
||||
var response;
|
||||
|
||||
// Request settings
|
||||
var settings = {};
|
||||
|
||||
// Disable header blacklist.
|
||||
// Not part of XHR specs.
|
||||
var disableHeaderCheck = false;
|
||||
|
||||
// Set some default headers
|
||||
var defaultHeaders = {
|
||||
"User-Agent": "node-XMLHttpRequest",
|
||||
"Accept": "*/*",
|
||||
};
|
||||
|
||||
var headers = {};
|
||||
var headersCase = {};
|
||||
|
||||
// These headers are not user setable.
|
||||
// The following are allowed but banned in the spec:
|
||||
// * user-agent
|
||||
var forbiddenRequestHeaders = [
|
||||
"accept-charset",
|
||||
"accept-encoding",
|
||||
"access-control-request-headers",
|
||||
"access-control-request-method",
|
||||
"connection",
|
||||
"content-length",
|
||||
"content-transfer-encoding",
|
||||
"cookie",
|
||||
"cookie2",
|
||||
"date",
|
||||
"expect",
|
||||
"host",
|
||||
"keep-alive",
|
||||
"origin",
|
||||
"referer",
|
||||
"te",
|
||||
"trailer",
|
||||
"transfer-encoding",
|
||||
"upgrade",
|
||||
"via"
|
||||
];
|
||||
|
||||
// These request methods are not allowed
|
||||
var forbiddenRequestMethods = [
|
||||
"TRACE",
|
||||
"TRACK",
|
||||
"CONNECT"
|
||||
];
|
||||
|
||||
// Send flag
|
||||
var sendFlag = false;
|
||||
// Error flag, used when errors occur or abort is called
|
||||
var errorFlag = false;
|
||||
|
||||
// Event listeners
|
||||
var listeners = {};
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
this.UNSENT = 0;
|
||||
this.OPENED = 1;
|
||||
this.HEADERS_RECEIVED = 2;
|
||||
this.LOADING = 3;
|
||||
this.DONE = 4;
|
||||
|
||||
/**
|
||||
* Public vars
|
||||
*/
|
||||
|
||||
// Current state
|
||||
this.readyState = this.UNSENT;
|
||||
|
||||
// default ready state change handler in case one is not set or is set late
|
||||
this.onreadystatechange = null;
|
||||
|
||||
// Result & response
|
||||
this.responseText = "";
|
||||
this.responseXML = "";
|
||||
this.status = null;
|
||||
this.statusText = null;
|
||||
|
||||
// Whether cross-site Access-Control requests should be made using
|
||||
// credentials such as cookies or authorization headers
|
||||
this.withCredentials = false;
|
||||
|
||||
/**
|
||||
* Private methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if the specified header is allowed.
|
||||
*
|
||||
* @param string header Header to validate
|
||||
* @return boolean False if not allowed, otherwise true
|
||||
*/
|
||||
var isAllowedHttpHeader = function(header) {
|
||||
return disableHeaderCheck || (header && forbiddenRequestHeaders.indexOf(header.toLowerCase()) === -1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the specified method is allowed.
|
||||
*
|
||||
* @param string method Request method to validate
|
||||
* @return boolean False if not allowed, otherwise true
|
||||
*/
|
||||
var isAllowedHttpMethod = function(method) {
|
||||
return (method && forbiddenRequestMethods.indexOf(method) === -1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Public methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Open the connection. Currently supports local server requests.
|
||||
*
|
||||
* @param string method Connection method (eg GET, POST)
|
||||
* @param string url URL for the connection.
|
||||
* @param boolean async Asynchronous connection. Default is true.
|
||||
* @param string user Username for basic authentication (optional)
|
||||
* @param string password Password for basic authentication (optional)
|
||||
*/
|
||||
this.open = function(method, url, async, user, password) {
|
||||
this.abort();
|
||||
errorFlag = false;
|
||||
|
||||
// Check for valid request method
|
||||
if (!isAllowedHttpMethod(method)) {
|
||||
throw new Error("SecurityError: Request method not allowed");
|
||||
}
|
||||
|
||||
settings = {
|
||||
"method": method,
|
||||
"url": url.toString(),
|
||||
"async": (typeof async !== "boolean" ? true : async),
|
||||
"user": user || null,
|
||||
"password": password || null
|
||||
};
|
||||
|
||||
setState(this.OPENED);
|
||||
};
|
||||
|
||||
/**
|
||||
* Disables or enables isAllowedHttpHeader() check the request. Enabled by default.
|
||||
* This does not conform to the W3C spec.
|
||||
*
|
||||
* @param boolean state Enable or disable header checking.
|
||||
*/
|
||||
this.setDisableHeaderCheck = function(state) {
|
||||
disableHeaderCheck = state;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a header for the request or appends the value if one is already set.
|
||||
*
|
||||
* @param string header Header name
|
||||
* @param string value Header value
|
||||
*/
|
||||
this.setRequestHeader = function(header, value) {
|
||||
if (this.readyState !== this.OPENED) {
|
||||
throw new Error("INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN");
|
||||
}
|
||||
if (!isAllowedHttpHeader(header)) {
|
||||
console.warn("Refused to set unsafe header \"" + header + "\"");
|
||||
return;
|
||||
}
|
||||
if (sendFlag) {
|
||||
throw new Error("INVALID_STATE_ERR: send flag is true");
|
||||
}
|
||||
header = headersCase[header.toLowerCase()] || header;
|
||||
headersCase[header.toLowerCase()] = header;
|
||||
headers[header] = headers[header] ? headers[header] + ', ' + value : value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a header from the server response.
|
||||
*
|
||||
* @param string header Name of header to get.
|
||||
* @return string Text of the header or null if it doesn't exist.
|
||||
*/
|
||||
this.getResponseHeader = function(header) {
|
||||
if (typeof header === "string"
|
||||
&& this.readyState > this.OPENED
|
||||
&& response
|
||||
&& response.headers
|
||||
&& response.headers[header.toLowerCase()]
|
||||
&& !errorFlag
|
||||
) {
|
||||
return response.headers[header.toLowerCase()];
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets all the response headers.
|
||||
*
|
||||
* @return string A string with all response headers separated by CR+LF
|
||||
*/
|
||||
this.getAllResponseHeaders = function() {
|
||||
if (this.readyState < this.HEADERS_RECEIVED || errorFlag) {
|
||||
return "";
|
||||
}
|
||||
var result = "";
|
||||
|
||||
for (var i in response.headers) {
|
||||
// Cookie headers are excluded
|
||||
if (i !== "set-cookie" && i !== "set-cookie2") {
|
||||
result += i + ": " + response.headers[i] + "\r\n";
|
||||
}
|
||||
}
|
||||
return result.substr(0, result.length - 2);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a request header
|
||||
*
|
||||
* @param string name Name of header to get
|
||||
* @return string Returns the request header or empty string if not set
|
||||
*/
|
||||
this.getRequestHeader = function(name) {
|
||||
if (typeof name === "string" && headersCase[name.toLowerCase()]) {
|
||||
return headers[headersCase[name.toLowerCase()]];
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends the request to the server.
|
||||
*
|
||||
* @param string data Optional data to send as request body.
|
||||
*/
|
||||
this.send = function(data) {
|
||||
if (this.readyState !== this.OPENED) {
|
||||
throw new Error("INVALID_STATE_ERR: connection must be opened before send() is called");
|
||||
}
|
||||
|
||||
if (sendFlag) {
|
||||
throw new Error("INVALID_STATE_ERR: send has already been called");
|
||||
}
|
||||
|
||||
var ssl = false, local = false;
|
||||
var url = Url.parse(settings.url);
|
||||
var host;
|
||||
// Determine the server
|
||||
switch (url.protocol) {
|
||||
case "https:":
|
||||
ssl = true;
|
||||
// SSL & non-SSL both need host, no break here.
|
||||
case "http:":
|
||||
host = url.hostname;
|
||||
break;
|
||||
|
||||
case "file:":
|
||||
local = true;
|
||||
break;
|
||||
|
||||
case undefined:
|
||||
case null:
|
||||
case "":
|
||||
host = "localhost";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Protocol not supported.");
|
||||
}
|
||||
|
||||
// Load files off the local filesystem (file://)
|
||||
if (local) {
|
||||
if (settings.method !== "GET") {
|
||||
throw new Error("XMLHttpRequest: Only GET method is supported");
|
||||
}
|
||||
|
||||
if (settings.async) {
|
||||
fs.readFile(url.pathname, "utf8", function(error, data) {
|
||||
if (error) {
|
||||
self.handleError(error);
|
||||
} else {
|
||||
self.status = 200;
|
||||
self.responseText = data;
|
||||
setState(self.DONE);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
this.responseText = fs.readFileSync(url.pathname, "utf8");
|
||||
this.status = 200;
|
||||
setState(self.DONE);
|
||||
} catch(e) {
|
||||
this.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Default to port 80. If accessing localhost on another port be sure
|
||||
// to use http://localhost:port/path
|
||||
var port = url.port || (ssl ? 443 : 80);
|
||||
// Add query string if one is used
|
||||
var uri = url.pathname + (url.search ? url.search : "");
|
||||
|
||||
// Set the defaults if they haven't been set
|
||||
for (var name in defaultHeaders) {
|
||||
if (!headersCase[name.toLowerCase()]) {
|
||||
headers[name] = defaultHeaders[name];
|
||||
}
|
||||
}
|
||||
|
||||
// Set the Host header or the server may reject the request
|
||||
headers.Host = host;
|
||||
if (!((ssl && port === 443) || port === 80)) {
|
||||
headers.Host += ":" + url.port;
|
||||
}
|
||||
|
||||
// Set Basic Auth if necessary
|
||||
if (settings.user) {
|
||||
if (typeof settings.password === "undefined") {
|
||||
settings.password = "";
|
||||
}
|
||||
var authBuf = new Buffer(settings.user + ":" + settings.password);
|
||||
headers.Authorization = "Basic " + authBuf.toString("base64");
|
||||
}
|
||||
|
||||
// Set content length header
|
||||
if (settings.method === "GET" || settings.method === "HEAD") {
|
||||
data = null;
|
||||
} else if (data) {
|
||||
headers["Content-Length"] = Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data);
|
||||
|
||||
if (!headers["Content-Type"]) {
|
||||
headers["Content-Type"] = "text/plain;charset=UTF-8";
|
||||
}
|
||||
} else if (settings.method === "POST") {
|
||||
// For a post with no data set Content-Length: 0.
|
||||
// This is required by buggy servers that don't meet the specs.
|
||||
headers["Content-Length"] = 0;
|
||||
}
|
||||
|
||||
var options = {
|
||||
host: host,
|
||||
port: port,
|
||||
path: uri,
|
||||
method: settings.method,
|
||||
headers: headers,
|
||||
agent: false,
|
||||
withCredentials: self.withCredentials
|
||||
};
|
||||
|
||||
// Reset error flag
|
||||
errorFlag = false;
|
||||
|
||||
// Handle async requests
|
||||
if (settings.async) {
|
||||
// Use the proper protocol
|
||||
var doRequest = ssl ? https.request : http.request;
|
||||
|
||||
// Request is being sent, set send flag
|
||||
sendFlag = true;
|
||||
|
||||
// As per spec, this is called here for historical reasons.
|
||||
self.dispatchEvent("readystatechange");
|
||||
|
||||
// Handler for the response
|
||||
var responseHandler = function responseHandler(resp) {
|
||||
// Set response var to the response we got back
|
||||
// This is so it remains accessable outside this scope
|
||||
response = resp;
|
||||
// Check for redirect
|
||||
// @TODO Prevent looped redirects
|
||||
if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {
|
||||
// Change URL to the redirect location
|
||||
settings.url = response.headers.location;
|
||||
var url = Url.parse(settings.url);
|
||||
// Set host var in case it's used later
|
||||
host = url.hostname;
|
||||
// Options for the new request
|
||||
var newOptions = {
|
||||
hostname: url.hostname,
|
||||
port: url.port,
|
||||
path: url.path,
|
||||
method: response.statusCode === 303 ? "GET" : settings.method,
|
||||
headers: headers,
|
||||
withCredentials: self.withCredentials
|
||||
};
|
||||
|
||||
// Issue the new request
|
||||
request = doRequest(newOptions, responseHandler).on("error", errorHandler);
|
||||
request.end();
|
||||
// @TODO Check if an XHR event needs to be fired here
|
||||
return;
|
||||
}
|
||||
|
||||
response.setEncoding("utf8");
|
||||
|
||||
setState(self.HEADERS_RECEIVED);
|
||||
self.status = response.statusCode;
|
||||
|
||||
response.on("data", function(chunk) {
|
||||
// Make sure there's some data
|
||||
if (chunk) {
|
||||
self.responseText += chunk;
|
||||
}
|
||||
// Don't emit state changes if the connection has been aborted.
|
||||
if (sendFlag) {
|
||||
setState(self.LOADING);
|
||||
}
|
||||
});
|
||||
|
||||
response.on("end", function() {
|
||||
if (sendFlag) {
|
||||
// Discard the end event if the connection has been aborted
|
||||
setState(self.DONE);
|
||||
sendFlag = false;
|
||||
}
|
||||
});
|
||||
|
||||
response.on("error", function(error) {
|
||||
self.handleError(error);
|
||||
});
|
||||
};
|
||||
|
||||
// Error handler for the request
|
||||
var errorHandler = function errorHandler(error) {
|
||||
self.handleError(error);
|
||||
};
|
||||
|
||||
// Create the request
|
||||
request = doRequest(options, responseHandler).on("error", errorHandler);
|
||||
|
||||
// Node 0.4 and later won't accept empty data. Make sure it's needed.
|
||||
if (data) {
|
||||
request.write(data);
|
||||
}
|
||||
|
||||
request.end();
|
||||
|
||||
self.dispatchEvent("loadstart");
|
||||
} else { // Synchronous
|
||||
// Create a temporary file for communication with the other Node process
|
||||
var contentFile = ".node-xmlhttprequest-content-" + process.pid;
|
||||
var syncFile = ".node-xmlhttprequest-sync-" + process.pid;
|
||||
fs.writeFileSync(syncFile, "", "utf8");
|
||||
// The async request the other Node process executes
|
||||
var execString = "var http = require('http'), https = require('https'), fs = require('fs');"
|
||||
+ "var doRequest = http" + (ssl ? "s" : "") + ".request;"
|
||||
+ "var options = " + JSON.stringify(options) + ";"
|
||||
+ "var responseText = '';"
|
||||
+ "var req = doRequest(options, function(response) {"
|
||||
+ "response.setEncoding('utf8');"
|
||||
+ "response.on('data', function(chunk) {"
|
||||
+ " responseText += chunk;"
|
||||
+ "});"
|
||||
+ "response.on('end', function() {"
|
||||
+ "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText}}), 'utf8');"
|
||||
+ "fs.unlinkSync('" + syncFile + "');"
|
||||
+ "});"
|
||||
+ "response.on('error', function(error) {"
|
||||
+ "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');"
|
||||
+ "fs.unlinkSync('" + syncFile + "');"
|
||||
+ "});"
|
||||
+ "}).on('error', function(error) {"
|
||||
+ "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');"
|
||||
+ "fs.unlinkSync('" + syncFile + "');"
|
||||
+ "});"
|
||||
+ (data ? "req.write('" + JSON.stringify(data).slice(1,-1).replace(/'/g, "\\'") + "');":"")
|
||||
+ "req.end();";
|
||||
// Start the other Node Process, executing this string
|
||||
var syncProc = spawn(process.argv[0], ["-e", execString]);
|
||||
while(fs.existsSync(syncFile)) {
|
||||
// Wait while the sync file is empty
|
||||
}
|
||||
var resp = JSON.parse(fs.readFileSync(contentFile, 'utf8'));
|
||||
// Kill the child process once the file has data
|
||||
syncProc.stdin.end();
|
||||
// Remove the temporary file
|
||||
fs.unlinkSync(contentFile);
|
||||
|
||||
if (resp.err) {
|
||||
self.handleError(resp.err);
|
||||
} else {
|
||||
response = resp.data;
|
||||
self.status = resp.data.statusCode;
|
||||
self.responseText = resp.data.text;
|
||||
setState(self.DONE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when an error is encountered to deal with it.
|
||||
*/
|
||||
this.handleError = function(error) {
|
||||
this.status = 0;
|
||||
this.statusText = error;
|
||||
this.responseText = error.stack;
|
||||
errorFlag = true;
|
||||
setState(this.DONE);
|
||||
this.dispatchEvent('error');
|
||||
};
|
||||
|
||||
/**
|
||||
* Aborts a request.
|
||||
*/
|
||||
this.abort = function() {
|
||||
if (request) {
|
||||
request.abort();
|
||||
request = null;
|
||||
}
|
||||
|
||||
headers = defaultHeaders;
|
||||
this.status = 0;
|
||||
this.responseText = "";
|
||||
this.responseXML = "";
|
||||
|
||||
errorFlag = true;
|
||||
|
||||
if (this.readyState !== this.UNSENT
|
||||
&& (this.readyState !== this.OPENED || sendFlag)
|
||||
&& this.readyState !== this.DONE) {
|
||||
sendFlag = false;
|
||||
setState(this.DONE);
|
||||
}
|
||||
this.readyState = this.UNSENT;
|
||||
this.dispatchEvent('abort');
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an event listener. Preferred method of binding to events.
|
||||
*/
|
||||
this.addEventListener = function(event, callback) {
|
||||
if (!(event in listeners)) {
|
||||
listeners[event] = [];
|
||||
}
|
||||
// Currently allows duplicate callbacks. Should it?
|
||||
listeners[event].push(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove an event callback that has already been bound.
|
||||
* Only works on the matching funciton, cannot be a copy.
|
||||
*/
|
||||
this.removeEventListener = function(event, callback) {
|
||||
if (event in listeners) {
|
||||
// Filter will return a new array with the callback removed
|
||||
listeners[event] = listeners[event].filter(function(ev) {
|
||||
return ev !== callback;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispatch any events, including both "on" methods and events attached using addEventListener.
|
||||
*/
|
||||
this.dispatchEvent = function(event) {
|
||||
if (typeof self["on" + event] === "function") {
|
||||
self["on" + event]();
|
||||
}
|
||||
if (event in listeners) {
|
||||
for (var i = 0, len = listeners[event].length; i < len; i++) {
|
||||
listeners[event][i].call(self);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Changes readyState and calls onreadystatechange.
|
||||
*
|
||||
* @param int state New state
|
||||
*/
|
||||
var setState = function(state) {
|
||||
if (state == self.LOADING || self.readyState !== state) {
|
||||
self.readyState = state;
|
||||
|
||||
if (settings.async || self.readyState < self.OPENED || self.readyState === self.DONE) {
|
||||
self.dispatchEvent("readystatechange");
|
||||
}
|
||||
|
||||
if (self.readyState === self.DONE && !errorFlag) {
|
||||
self.dispatchEvent("load");
|
||||
// @TODO figure out InspectorInstrumentation::didLoadXHR(cookie)
|
||||
self.dispatchEvent("loadend");
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
9
test3/httpPut/httpPut.js
Normal file
9
test3/httpPut/httpPut.js
Normal file
@ -0,0 +1,9 @@
|
||||
const httpPut = (url, data, callback, err = console.error) => {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open("PUT", url, true);
|
||||
request.setRequestHeader('Content-type','application/json; charset=utf-8');
|
||||
request.onload = () => callback(request);
|
||||
request.onerror = () => err(request);
|
||||
request.send(data);
|
||||
};
|
||||
module.exports = httpPut;
|
||||
8
test3/httpPut/httpPut.test.js
Normal file
8
test3/httpPut/httpPut.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const httpPut = require('./httpPut.js');
|
||||
|
||||
test('Testing httpPut', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof httpPut === 'function').toBeTruthy();
|
||||
});
|
||||
4
test3/httpsRedirect/httpsRedirect.js
Normal file
4
test3/httpsRedirect/httpsRedirect.js
Normal file
@ -0,0 +1,4 @@
|
||||
const httpsRedirect = () => {
|
||||
if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]);
|
||||
};
|
||||
module.exports = httpsRedirect;
|
||||
8
test3/httpsRedirect/httpsRedirect.test.js
Normal file
8
test3/httpsRedirect/httpsRedirect.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const httpsRedirect = require('./httpsRedirect.js');
|
||||
|
||||
test('Testing httpsRedirect', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof httpsRedirect === 'function').toBeTruthy();
|
||||
});
|
||||
6
test3/hz/hz.js
Normal file
6
test3/hz/hz.js
Normal file
@ -0,0 +1,6 @@
|
||||
const hz = (fn, iterations = 100) => {
|
||||
const before = performance.now();
|
||||
for (let i = 0; i < iterations; i++) fn();
|
||||
return 1000 * iterations / (performance.now() - before);
|
||||
};
|
||||
module.exports = hz;
|
||||
8
test3/hz/hz.test.js
Normal file
8
test3/hz/hz.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const hz = require('./hz.js');
|
||||
|
||||
test('Testing hz', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof hz === 'function').toBeTruthy();
|
||||
});
|
||||
5
test3/inRange/inRange.js
Normal file
5
test3/inRange/inRange.js
Normal file
@ -0,0 +1,5 @@
|
||||
const inRange = (n, start, end = null) => {
|
||||
if (end && start > end) end = [start, (start = end)][0];
|
||||
return end == null ? n >= 0 && n < start : n >= start && n < end;
|
||||
};
|
||||
module.exports = inRange;
|
||||
12
test3/inRange/inRange.test.js
Normal file
12
test3/inRange/inRange.test.js
Normal file
@ -0,0 +1,12 @@
|
||||
const expect = require('expect');
|
||||
const inRange = require('./inRange.js');
|
||||
|
||||
test('Testing inRange', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof inRange === 'function').toBeTruthy();
|
||||
expect(inRange(3, 2, 5)).toBe(true);
|
||||
expect(inRange(3, 4)).toBe(true);
|
||||
expect(inRange(2, 3, 5)).toBe(false);
|
||||
expect(inRange(3, 2)).toBe(false);
|
||||
});
|
||||
6
test3/indexOfAll/indexOfAll.js
Normal file
6
test3/indexOfAll/indexOfAll.js
Normal file
@ -0,0 +1,6 @@
|
||||
const indexOfAll = (arr, val) => {
|
||||
const indices = [];
|
||||
arr.forEach((el, i) => el === val && indices.push(i));
|
||||
return indices;
|
||||
};
|
||||
module.exports = indexOfAll;
|
||||
10
test3/indexOfAll/indexOfAll.test.js
Normal file
10
test3/indexOfAll/indexOfAll.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
const expect = require('expect');
|
||||
const indexOfAll = require('./indexOfAll.js');
|
||||
|
||||
test('Testing indexOfAll', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof indexOfAll === 'function').toBeTruthy();
|
||||
expect(indexOfAll([1, 2, 3, 1, 2, 3], 1)).toEqual([0,3]);
|
||||
expect(indexOfAll([1, 2, 3], 4)).toEqual([]);
|
||||
});
|
||||
2
test3/initial/initial.js
Normal file
2
test3/initial/initial.js
Normal file
@ -0,0 +1,2 @@
|
||||
const initial = arr => arr.slice(0, -1);
|
||||
module.exports = initial;
|
||||
9
test3/initial/initial.test.js
Normal file
9
test3/initial/initial.test.js
Normal file
@ -0,0 +1,9 @@
|
||||
const expect = require('expect');
|
||||
const initial = require('./initial.js');
|
||||
|
||||
test('Testing initial', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof initial === 'function').toBeTruthy();
|
||||
expect(initial([1, 2, 3])).toEqual([1, 2]);
|
||||
});
|
||||
3
test3/initialize2DArray/initialize2DArray.js
Normal file
3
test3/initialize2DArray/initialize2DArray.js
Normal file
@ -0,0 +1,3 @@
|
||||
const initialize2DArray = (w, h, val = null) =>
|
||||
Array.from({ length: h }).map(() => Array.from({ length: w }).fill(val));
|
||||
module.exports = initialize2DArray;
|
||||
9
test3/initialize2DArray/initialize2DArray.test.js
Normal file
9
test3/initialize2DArray/initialize2DArray.test.js
Normal file
@ -0,0 +1,9 @@
|
||||
const expect = require('expect');
|
||||
const initialize2DArray = require('./initialize2DArray.js');
|
||||
|
||||
test('Testing initialize2DArray', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof initialize2DArray === 'function').toBeTruthy();
|
||||
expect(initialize2DArray(2, 2, 0)).toEqual([[0,0], [0,0]]);
|
||||
});
|
||||
@ -0,0 +1,3 @@
|
||||
const initializeArrayWithRange = (end, start = 0, step = 1) =>
|
||||
Array.from({ length: Math.ceil((end + 1 - start) / step) }).map((v, i) => i * step + start);
|
||||
module.exports = initializeArrayWithRange;
|
||||
@ -0,0 +1,9 @@
|
||||
const expect = require('expect');
|
||||
const initializeArrayWithRange = require('./initializeArrayWithRange.js');
|
||||
|
||||
test('Testing initializeArrayWithRange', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof initializeArrayWithRange === 'function').toBeTruthy();
|
||||
expect(initializeArrayWithRange(5)).toEqual([0, 1, 2, 3, 4, 5]);
|
||||
});
|
||||
@ -0,0 +1,5 @@
|
||||
const initializeArrayWithRangeRight = (end, start = 0, step = 1) =>
|
||||
Array.from({ length: Math.ceil((end + 1 - start) / step) }).map(
|
||||
(v, i, arr) => (arr.length - i - 1) * step + start
|
||||
);
|
||||
module.exports = initializeArrayWithRangeRight;
|
||||
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const initializeArrayWithRangeRight = require('./initializeArrayWithRangeRight.js');
|
||||
|
||||
test('Testing initializeArrayWithRangeRight', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof initializeArrayWithRangeRight === 'function').toBeTruthy();
|
||||
});
|
||||
@ -0,0 +1,2 @@
|
||||
const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val);
|
||||
module.exports = initializeArrayWithValues;
|
||||
@ -0,0 +1,9 @@
|
||||
const expect = require('expect');
|
||||
const initializeArrayWithValues = require('./initializeArrayWithValues.js');
|
||||
|
||||
test('Testing initializeArrayWithValues', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof initializeArrayWithValues === 'function').toBeTruthy();
|
||||
expect(initializeArrayWithValues(5, 2)).toEqual([2, 2, 2, 2, 2]);
|
||||
});
|
||||
5
test3/initializeNDArray/initializeNDArray.js
Normal file
5
test3/initializeNDArray/initializeNDArray.js
Normal file
@ -0,0 +1,5 @@
|
||||
const initializeNDArray = (val, ...args) =>
|
||||
args.length === 0
|
||||
? val
|
||||
: Array.from({ length: args[0] }).map(() => initializeNDArray(val, ...args.slice(1)));
|
||||
module.exports = initializeNDArray;
|
||||
8
test3/initializeNDArray/initializeNDArray.test.js
Normal file
8
test3/initializeNDArray/initializeNDArray.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const initializeNDArray = require('./initializeNDArray.js');
|
||||
|
||||
test('Testing initializeNDArray', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof initializeNDArray === 'function').toBeTruthy();
|
||||
});
|
||||
5
test3/intersection/intersection.js
Normal file
5
test3/intersection/intersection.js
Normal file
@ -0,0 +1,5 @@
|
||||
const intersection = (a, b) => {
|
||||
const s = new Set(b);
|
||||
return a.filter(x => s.has(x));
|
||||
};
|
||||
module.exports = intersection;
|
||||
9
test3/intersection/intersection.test.js
Normal file
9
test3/intersection/intersection.test.js
Normal file
@ -0,0 +1,9 @@
|
||||
const expect = require('expect');
|
||||
const intersection = require('./intersection.js');
|
||||
|
||||
test('Testing intersection', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof intersection === 'function').toBeTruthy();
|
||||
expect(intersection([1, 2, 3], [4, 3, 2])).toEqual([2, 3]);
|
||||
});
|
||||
5
test3/intersectionBy/intersectionBy.js
Normal file
5
test3/intersectionBy/intersectionBy.js
Normal file
@ -0,0 +1,5 @@
|
||||
const intersectionBy = (a, b, fn) => {
|
||||
const s = new Set(b.map(x => fn(x)));
|
||||
return a.filter(x => s.has(fn(x)));
|
||||
};
|
||||
module.exports = intersectionBy;
|
||||
9
test3/intersectionBy/intersectionBy.test.js
Normal file
9
test3/intersectionBy/intersectionBy.test.js
Normal file
@ -0,0 +1,9 @@
|
||||
const expect = require('expect');
|
||||
const intersectionBy = require('./intersectionBy.js');
|
||||
|
||||
test('Testing intersectionBy', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof intersectionBy === 'function').toBeTruthy();
|
||||
expect(intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor)).toEqual([2.1]);
|
||||
});
|
||||
2
test3/intersectionWith/intersectionWith.js
Normal file
2
test3/intersectionWith/intersectionWith.js
Normal file
@ -0,0 +1,2 @@
|
||||
const intersectionWith = (a, b, comp) => a.filter(x => b.findIndex(y => comp(x, y)) !== -1);
|
||||
module.exports = intersectionWith;
|
||||
11
test3/intersectionWith/intersectionWith.test.js
Normal file
11
test3/intersectionWith/intersectionWith.test.js
Normal file
@ -0,0 +1,11 @@
|
||||
const expect = require('expect');
|
||||
const intersectionWith = require('./intersectionWith.js');
|
||||
|
||||
test('Testing intersectionWith', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof intersectionWith === 'function').toBeTruthy();
|
||||
expect(
|
||||
intersectionWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0, 3.9], (a, b) => Math.round(a) === Math.round(b))
|
||||
).toEqual([1.5, 3, 0]);
|
||||
});
|
||||
8
test3/invertKeyValues/invertKeyValues.js
Normal file
8
test3/invertKeyValues/invertKeyValues.js
Normal file
@ -0,0 +1,8 @@
|
||||
const invertKeyValues = (obj, fn) =>
|
||||
Object.keys(obj).reduce((acc, key) => {
|
||||
const val = fn ? fn(obj[key]) : obj[key];
|
||||
acc[val] = acc[val] || [];
|
||||
acc[val].push(key);
|
||||
return acc;
|
||||
}, {});
|
||||
module.exports = invertKeyValues;
|
||||
10
test3/invertKeyValues/invertKeyValues.test.js
Normal file
10
test3/invertKeyValues/invertKeyValues.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
const expect = require('expect');
|
||||
const invertKeyValues = require('./invertKeyValues.js');
|
||||
|
||||
test('Testing invertKeyValues', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof invertKeyValues === 'function').toBeTruthy();
|
||||
expect(invertKeyValues({ a: 1, b: 2, c: 1 })).toEqual({ 1: [ 'a', 'c' ], 2: [ 'b' ] });
|
||||
expect(invertKeyValues({ a: 1, b: 2, c: 1 }, value => 'group' + value)).toEqual({ group1: [ 'a', 'c' ], group2: [ 'b' ] });
|
||||
});
|
||||
2
test3/is/is.js
Normal file
2
test3/is/is.js
Normal file
@ -0,0 +1,2 @@
|
||||
const is = (type, val) => ![, null].includes(val) && val.constructor === type;
|
||||
module.exports = is;
|
||||
24
test3/is/is.test.js
Normal file
24
test3/is/is.test.js
Normal file
@ -0,0 +1,24 @@
|
||||
const expect = require('expect');
|
||||
const is = require('./is.js');
|
||||
|
||||
test('Testing is', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof is === 'function').toBeTruthy();
|
||||
expect(is(Array, [1])).toBeTruthy();
|
||||
expect(is(Array, [])).toBeTruthy();
|
||||
expect(is(Array, {})).toBeFalsy();
|
||||
expect(is(Object, {})).toBeTruthy();
|
||||
expect(is(Map, new Map())).toBeTruthy();
|
||||
expect(is(RegExp, /./g)).toBeTruthy();
|
||||
expect(is(Set, new Set())).toBeTruthy();
|
||||
expect(is(WeakMap, new WeakMap())).toBeTruthy();
|
||||
expect(is(WeakSet, new WeakSet())).toBeTruthy();
|
||||
expect(is(String, '')).toBeTruthy();
|
||||
expect(is(String, new String(''))).toBeTruthy();
|
||||
expect(is(Number, 1)).toBeTruthy();
|
||||
expect(is(Number, new Number('10'))).toBeTruthy();
|
||||
expect(is(Boolean, false)).toBeTruthy();
|
||||
expect(is(Boolean, new Boolean(false))).toBeTruthy();
|
||||
expect(is(Function, () => null)).toBeTruthy();
|
||||
});
|
||||
2
test3/isAbsoluteURL/isAbsoluteURL.js
Normal file
2
test3/isAbsoluteURL/isAbsoluteURL.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isAbsoluteURL = str => /^[a-z][a-z0-9+.-]*:/.test(str);
|
||||
module.exports = isAbsoluteURL;
|
||||
11
test3/isAbsoluteURL/isAbsoluteURL.test.js
Normal file
11
test3/isAbsoluteURL/isAbsoluteURL.test.js
Normal file
@ -0,0 +1,11 @@
|
||||
const expect = require('expect');
|
||||
const isAbsoluteURL = require('./isAbsoluteURL.js');
|
||||
|
||||
test('Testing isAbsoluteURL', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isAbsoluteURL === 'function').toBeTruthy();
|
||||
expect(isAbsoluteURL('https://google.com')).toBe(true);
|
||||
expect(isAbsoluteURL('ftp://www.myserver.net')).toBe(true);
|
||||
expect(isAbsoluteURL('/foo/bar')).toBe(false);
|
||||
});
|
||||
11
test3/isAnagram/isAnagram.js
Normal file
11
test3/isAnagram/isAnagram.js
Normal file
@ -0,0 +1,11 @@
|
||||
const isAnagram = (str1, str2) => {
|
||||
const normalize = str =>
|
||||
str
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]/gi, '')
|
||||
.split('')
|
||||
.sort()
|
||||
.join('');
|
||||
return normalize(str1) === normalize(str2);
|
||||
};
|
||||
module.exports = isAnagram;
|
||||
12
test3/isAnagram/isAnagram.test.js
Normal file
12
test3/isAnagram/isAnagram.test.js
Normal file
@ -0,0 +1,12 @@
|
||||
const expect = require('expect');
|
||||
const isAnagram = require('./isAnagram.js');
|
||||
|
||||
test('Testing isAnagram', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isAnagram === 'function').toBeTruthy();
|
||||
expect(isAnagram('iceman', 'cinema')).toBeTruthy();
|
||||
expect(isAnagram('rail safety', 'fairy tales')).toBeTruthy();
|
||||
expect(isAnagram('roast beef', 'eat for BSE')).toBeTruthy();
|
||||
expect(isAnagram('Regera Dowdy', 'E. G. Deadworry')).toBeTruthy();
|
||||
});
|
||||
5
test3/isArmstrongNumber/isArmstrongNumber.js
Normal file
5
test3/isArmstrongNumber/isArmstrongNumber.js
Normal file
@ -0,0 +1,5 @@
|
||||
const isArmstrongNumber = digits =>
|
||||
(arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)(
|
||||
(digits + '').split('')
|
||||
);
|
||||
module.exports = isArmstrongNumber;
|
||||
8
test3/isArmstrongNumber/isArmstrongNumber.test.js
Normal file
8
test3/isArmstrongNumber/isArmstrongNumber.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const isArmstrongNumber = require('./isArmstrongNumber.js');
|
||||
|
||||
test('Testing isArmstrongNumber', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isArmstrongNumber === 'function').toBeTruthy();
|
||||
});
|
||||
2
test3/isArray/isArray.js
Normal file
2
test3/isArray/isArray.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isArray = val => Array.isArray(val);
|
||||
module.exports = isArray;
|
||||
10
test3/isArray/isArray.test.js
Normal file
10
test3/isArray/isArray.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
const expect = require('expect');
|
||||
const isArray = require('./isArray.js');
|
||||
|
||||
test('Testing isArray', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isArray === 'function').toBeTruthy();
|
||||
expect(isArray([1])).toBe(true);
|
||||
expect(isArray('array')).toBe(false);
|
||||
});
|
||||
2
test3/isArrayBuffer/isArrayBuffer.js
Normal file
2
test3/isArrayBuffer/isArrayBuffer.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isArrayBuffer = val => val instanceof ArrayBuffer;
|
||||
module.exports = isArrayBuffer;
|
||||
8
test3/isArrayBuffer/isArrayBuffer.test.js
Normal file
8
test3/isArrayBuffer/isArrayBuffer.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const isArrayBuffer = require('./isArrayBuffer.js');
|
||||
|
||||
test('Testing isArrayBuffer', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isArrayBuffer === 'function').toBeTruthy();
|
||||
});
|
||||
8
test3/isArrayLike/isArrayLike.js
Normal file
8
test3/isArrayLike/isArrayLike.js
Normal file
@ -0,0 +1,8 @@
|
||||
const isArrayLike = val => {
|
||||
try {
|
||||
return [...val], true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
module.exports = isArrayLike;
|
||||
11
test3/isArrayLike/isArrayLike.test.js
Normal file
11
test3/isArrayLike/isArrayLike.test.js
Normal file
@ -0,0 +1,11 @@
|
||||
const expect = require('expect');
|
||||
const isArrayLike = require('./isArrayLike.js');
|
||||
|
||||
test('Testing isArrayLike', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isArrayLike === 'function').toBeTruthy();
|
||||
expect(isArrayLike('abc')).toBe(true);
|
||||
expect(isArrayLike([1,2,3])).toBe(true);
|
||||
expect(isArrayLike(null)).toBe(false);
|
||||
});
|
||||
2
test3/isBoolean/isBoolean.js
Normal file
2
test3/isBoolean/isBoolean.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isBoolean = val => typeof val === 'boolean';
|
||||
module.exports = isBoolean;
|
||||
10
test3/isBoolean/isBoolean.test.js
Normal file
10
test3/isBoolean/isBoolean.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
const expect = require('expect');
|
||||
const isBoolean = require('./isBoolean.js');
|
||||
|
||||
test('Testing isBoolean', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isBoolean === 'function').toBeTruthy();
|
||||
expect(isBoolean(null)).toBe(false);
|
||||
expect(isBoolean(false)).toBe(true);
|
||||
});
|
||||
2
test3/isBrowser/isBrowser.js
Normal file
2
test3/isBrowser/isBrowser.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isBrowser = () => ![typeof window, typeof document].includes('undefined');
|
||||
module.exports = isBrowser;
|
||||
8
test3/isBrowser/isBrowser.test.js
Normal file
8
test3/isBrowser/isBrowser.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const isBrowser = require('./isBrowser.js');
|
||||
|
||||
test('Testing isBrowser', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isBrowser === 'function').toBeTruthy();
|
||||
});
|
||||
2
test3/isBrowserTabFocused/isBrowserTabFocused.js
Normal file
2
test3/isBrowserTabFocused/isBrowserTabFocused.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isBrowserTabFocused = () => !document.hidden;
|
||||
module.exports = isBrowserTabFocused;
|
||||
8
test3/isBrowserTabFocused/isBrowserTabFocused.test.js
Normal file
8
test3/isBrowserTabFocused/isBrowserTabFocused.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const isBrowserTabFocused = require('./isBrowserTabFocused.js');
|
||||
|
||||
test('Testing isBrowserTabFocused', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isBrowserTabFocused === 'function').toBeTruthy();
|
||||
});
|
||||
2
test3/isDivisible/isDivisible.js
Normal file
2
test3/isDivisible/isDivisible.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isDivisible = (dividend, divisor) => dividend % divisor === 0;
|
||||
module.exports = isDivisible;
|
||||
9
test3/isDivisible/isDivisible.test.js
Normal file
9
test3/isDivisible/isDivisible.test.js
Normal file
@ -0,0 +1,9 @@
|
||||
const expect = require('expect');
|
||||
const isDivisible = require('./isDivisible.js');
|
||||
|
||||
test('Testing isDivisible', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isDivisible === 'function').toBeTruthy();
|
||||
expect(isDivisible(6, 3)).toBe(true);
|
||||
});
|
||||
2
test3/isEmpty/isEmpty.js
Normal file
2
test3/isEmpty/isEmpty.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isEmpty = val => val == null || !(Object.keys(val) || val).length;
|
||||
module.exports = isEmpty;
|
||||
18
test3/isEmpty/isEmpty.test.js
Normal file
18
test3/isEmpty/isEmpty.test.js
Normal file
@ -0,0 +1,18 @@
|
||||
const expect = require('expect');
|
||||
const isEmpty = require('./isEmpty.js');
|
||||
|
||||
test('Testing isEmpty', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isEmpty === 'function').toBeTruthy();
|
||||
expect(isEmpty(new Map())).toBe(true);
|
||||
expect(isEmpty(new Set())).toBe(true);
|
||||
expect(isEmpty([])).toBe(true);
|
||||
expect(isEmpty({})).toBe(true);
|
||||
expect(isEmpty('')).toBe(true);
|
||||
expect(isEmpty([1, 2])).toBe(false);
|
||||
expect(isEmpty({ a: 1, b: 2 })).toBe(false);
|
||||
expect(isEmpty('text')).toBe(false);
|
||||
expect(isEmpty(123)).toBe(true);
|
||||
expect(isEmpty(true)).toBe(true);
|
||||
});
|
||||
2
test3/isEven/isEven.js
Normal file
2
test3/isEven/isEven.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isEven = num => num % 2 === 0;
|
||||
module.exports = isEven;
|
||||
10
test3/isEven/isEven.test.js
Normal file
10
test3/isEven/isEven.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
const expect = require('expect');
|
||||
const isEven = require('./isEven.js');
|
||||
|
||||
test('Testing isEven', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isEven === 'function').toBeTruthy();
|
||||
expect(isEven(4)).toBe(true);
|
||||
expect(isEven(5)).toBeFalsy();
|
||||
});
|
||||
2
test3/isFunction/isFunction.js
Normal file
2
test3/isFunction/isFunction.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isFunction = val => typeof val === 'function';
|
||||
module.exports = isFunction;
|
||||
10
test3/isFunction/isFunction.test.js
Normal file
10
test3/isFunction/isFunction.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
const expect = require('expect');
|
||||
const isFunction = require('./isFunction.js');
|
||||
|
||||
test('Testing isFunction', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isFunction === 'function').toBeTruthy();
|
||||
expect(isFunction(x => x)).toBe(true);
|
||||
expect(isFunction('x')).toBe(false);
|
||||
});
|
||||
2
test3/isLowerCase/isLowerCase.js
Normal file
2
test3/isLowerCase/isLowerCase.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isLowerCase = str => str === str.toLowerCase();
|
||||
module.exports = isLowerCase;
|
||||
11
test3/isLowerCase/isLowerCase.test.js
Normal file
11
test3/isLowerCase/isLowerCase.test.js
Normal file
@ -0,0 +1,11 @@
|
||||
const expect = require('expect');
|
||||
const isLowerCase = require('./isLowerCase.js');
|
||||
|
||||
test('Testing isLowerCase', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isLowerCase === 'function').toBeTruthy();
|
||||
expect(isLowerCase('abc')).toBe(true);
|
||||
expect(isLowerCase('a3@$')).toBe(true);
|
||||
expect(isLowerCase('A3@$')).toBe(false);
|
||||
});
|
||||
2
test3/isMap/isMap.js
Normal file
2
test3/isMap/isMap.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isMap = val => val instanceof Map;
|
||||
module.exports = isMap;
|
||||
8
test3/isMap/isMap.test.js
Normal file
8
test3/isMap/isMap.test.js
Normal file
@ -0,0 +1,8 @@
|
||||
const expect = require('expect');
|
||||
const isMap = require('./isMap.js');
|
||||
|
||||
test('Testing isMap', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isMap === 'function').toBeTruthy();
|
||||
});
|
||||
2
test3/isNil/isNil.js
Normal file
2
test3/isNil/isNil.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isNil = val => val === undefined || val === null;
|
||||
module.exports = isNil;
|
||||
11
test3/isNil/isNil.test.js
Normal file
11
test3/isNil/isNil.test.js
Normal file
@ -0,0 +1,11 @@
|
||||
const expect = require('expect');
|
||||
const isNil = require('./isNil.js');
|
||||
|
||||
test('Testing isNil', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isNil === 'function').toBeTruthy();
|
||||
expect(isNil(null)).toBe(true);
|
||||
expect(isNil(undefined)).toBe(true);
|
||||
expect(isNil('')).toBe(false);
|
||||
});
|
||||
2
test3/isNull/isNull.js
Normal file
2
test3/isNull/isNull.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isNull = val => val === null;
|
||||
module.exports = isNull;
|
||||
10
test3/isNull/isNull.test.js
Normal file
10
test3/isNull/isNull.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
const expect = require('expect');
|
||||
const isNull = require('./isNull.js');
|
||||
|
||||
test('Testing isNull', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isNull === 'function').toBeTruthy();
|
||||
expect(isNull(null)).toBe(true);
|
||||
expect(isNull(NaN)).toBe(false);
|
||||
});
|
||||
2
test3/isNumber/isNumber.js
Normal file
2
test3/isNumber/isNumber.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isNumber = val => typeof val === 'number';
|
||||
module.exports = isNumber;
|
||||
10
test3/isNumber/isNumber.test.js
Normal file
10
test3/isNumber/isNumber.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
const expect = require('expect');
|
||||
const isNumber = require('./isNumber.js');
|
||||
|
||||
test('Testing isNumber', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isNumber === 'function').toBeTruthy();
|
||||
expect(isNumber(1)).toBe(true);
|
||||
expect(isNumber('1')).toBe(false);
|
||||
});
|
||||
2
test3/isObject/isObject.js
Normal file
2
test3/isObject/isObject.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isObject = obj => obj === Object(obj);
|
||||
module.exports = isObject;
|
||||
13
test3/isObject/isObject.test.js
Normal file
13
test3/isObject/isObject.test.js
Normal file
@ -0,0 +1,13 @@
|
||||
const expect = require('expect');
|
||||
const isObject = require('./isObject.js');
|
||||
|
||||
test('Testing isObject', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isObject === 'function').toBeTruthy();
|
||||
|
||||
expect(isObject([1, 2, 3, 4])).toBeTruthy();
|
||||
expect(isObject([])).toBeTruthy();
|
||||
expect(isObject({ a:1 })).toBeTruthy();
|
||||
expect(isObject(true)).toBeFalsy();
|
||||
});
|
||||
2
test3/isObjectLike/isObjectLike.js
Normal file
2
test3/isObjectLike/isObjectLike.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isObjectLike = val => val !== null && typeof val === 'object';
|
||||
module.exports = isObjectLike;
|
||||
12
test3/isObjectLike/isObjectLike.test.js
Normal file
12
test3/isObjectLike/isObjectLike.test.js
Normal file
@ -0,0 +1,12 @@
|
||||
const expect = require('expect');
|
||||
const isObjectLike = require('./isObjectLike.js');
|
||||
|
||||
test('Testing isObjectLike', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isObjectLike === 'function').toBeTruthy();
|
||||
expect(isObjectLike({})).toBe(true);
|
||||
expect(isObjectLike([1, 2, 3])).toBe(true);
|
||||
expect(isObjectLike(x => x)).toBe(false);
|
||||
expect(isObjectLike(null)).toBe(false);
|
||||
});
|
||||
2
test3/isPlainObject/isPlainObject.js
Normal file
2
test3/isPlainObject/isPlainObject.js
Normal file
@ -0,0 +1,2 @@
|
||||
const isPlainObject = val => !!val && typeof val === 'object' && val.constructor === Object;
|
||||
module.exports = isPlainObject;
|
||||
10
test3/isPlainObject/isPlainObject.test.js
Normal file
10
test3/isPlainObject/isPlainObject.test.js
Normal file
@ -0,0 +1,10 @@
|
||||
const expect = require('expect');
|
||||
const isPlainObject = require('./isPlainObject.js');
|
||||
|
||||
test('Testing isPlainObject', () => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
expect(typeof isPlainObject === 'function').toBeTruthy();
|
||||
expect(isPlainObject({ a: 1 })).toBe(true);
|
||||
expect(isPlainObject(new Map())).toBe(false);
|
||||
});
|
||||
Reference in New Issue
Block a user