mirror of https://github.com/01-edu/public.git
add js files
This commit is contained in:
parent
10ba7a0406
commit
c51609ed9e
|
@ -0,0 +1,18 @@
|
|||
Math.abs = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => isPositive(3))
|
||||
t(() => isPositive(1998790))
|
||||
t(() => !isPositive(-1))
|
||||
t(() => !isPositive(-0.7))
|
||||
t(() => !isPositive(-787823))
|
||||
t(() => !isPositive(0))
|
||||
|
||||
t(({ eq }) => eq(abs(0), 0))
|
||||
t(({ eq }) => eq(abs(-1), 1))
|
||||
t(({ eq }) => eq(abs(-13.2), 13.2))
|
||||
t(({ eq }) => eq(abs(132), 132))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,49 @@
|
|||
Promise.all = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// it should work with an empty object
|
||||
t(async ({ eq }) => eq(await all({}), {}))
|
||||
|
||||
// it should work with synchronous values
|
||||
t(async ({ eq }) => eq(await all({ a: 1, b: true }), { a: 1, b: true }))
|
||||
|
||||
// it should work with pending promises
|
||||
t(async ({ eq }) =>
|
||||
eq(
|
||||
await all({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(true),
|
||||
}),
|
||||
{ a: 1, b: true },
|
||||
),
|
||||
)
|
||||
|
||||
// it should work with pending promises and synchronous values
|
||||
t(async ({ eq, ctx }) =>
|
||||
eq(
|
||||
await all(
|
||||
Object.freeze({
|
||||
a: Promise.resolve(ctx).then((v) => v + 1),
|
||||
b: ctx,
|
||||
}),
|
||||
),
|
||||
{ a: ctx + 1, b: ctx },
|
||||
),
|
||||
)
|
||||
|
||||
// it should fail if one of the promises reject
|
||||
t(async ({ eq }) =>
|
||||
eq(
|
||||
await all({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.reject(Error('oops')),
|
||||
}).catch((err) => err.message),
|
||||
'oops',
|
||||
),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = Math.random
|
|
@ -0,0 +1,9 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => Array.isArray(arr)) // arr is declared and is an array
|
||||
t(({ eq }) => eq(arr[0], 4)) // arr first element is 4
|
||||
t(({ eq }) => eq(arr[1], '2')) // arr second element is "2"
|
||||
t(({ eq }) => eq(arr.length, 2)) // arr length is 2
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,19 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// bigger
|
||||
t(() => typeof biggie !== 'undefined')
|
||||
t(() => biggie > 1.7976931348623157e308)
|
||||
|
||||
// smaller
|
||||
t(() => typeof smalls !== 'undefined')
|
||||
t(() => smalls < -1.7976931348623157e308)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
/*
|
||||
“Damn right I like the life I live,
|
||||
because I went from negative to positive.”
|
||||
|
||||
― The Notorius B.I.G
|
||||
*/
|
|
@ -0,0 +1,18 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => bloodySunday(new Date('0001-01-01')) === 'Monday')
|
||||
t(() => bloodySunday(new Date('0001-01-02')) === 'Tuesday')
|
||||
t(() => bloodySunday(new Date('0001-01-03')) === 'Wednesday')
|
||||
t(() => bloodySunday(new Date('0001-01-04')) === 'Thursday')
|
||||
t(() => bloodySunday(new Date('0001-01-05')) === 'Friday')
|
||||
t(() => bloodySunday(new Date('0001-01-06')) === 'Saturday')
|
||||
t(() => bloodySunday(new Date('0001-01-07')) === 'Monday')
|
||||
|
||||
t(() => bloodySunday(new Date('0001-12-01')) === 'Friday')
|
||||
t(() => bloodySunday(new Date('1664-08-09')) === 'Saturday')
|
||||
|
||||
t(() => bloodySunday(new Date('2020-01-01')) === 'Monday')
|
||||
t(() => bloodySunday(new Date('2048-12-08')) === 'Thursday')
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,10 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(capitalize('str'), 'Str'))
|
||||
t(({ eq }) => eq(capitalize('qsdqsdqsd'), 'Qsdqsdqsd'))
|
||||
t(({ eq }) => eq(capitalize('STR'), 'Str'))
|
||||
t(({ eq }) => eq(capitalize('zapZAP'), 'Zapzap'))
|
||||
t(({ eq }) => eq(capitalize('zap ZAP'), 'Zap zap'))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,29 @@
|
|||
const sourceObject = {
|
||||
num: 42,
|
||||
bool: true,
|
||||
str: 'some text',
|
||||
log: console.log,
|
||||
}
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// Get
|
||||
t(({ eq }) => eq(typeof get, 'function'))
|
||||
t(({ eq }) => eq(typeof get, 'function'))
|
||||
t(({ eq }) => eq(get('num'), 42))
|
||||
t(({ eq }) => eq(get('bool'), true))
|
||||
t(({ eq }) => eq(get('str'), 'some text'))
|
||||
t(({ eq }) => eq(get('log'), console.log))
|
||||
t(({ eq }) => eq(get('noexist'), undefined))
|
||||
|
||||
// Set
|
||||
t(({ eq }) => eq(typeof set, 'function'))
|
||||
t(({ eq }) => eq(set('num', 55), 55))
|
||||
t(({ eq }) => eq(set('noexist', 'nice'), 'nice'))
|
||||
t(({ eq }) => eq(get('num'), 55))
|
||||
t(({ eq }) => eq(get('noexist'), 'nice'))
|
||||
t(({ eq }) => eq(set('log'), undefined))
|
||||
t(({ eq }) => eq(get('log'), undefined))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,8 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// prettier-ignore
|
||||
t(({ eq }) => eq(chunk(['a', 'b', 'c', 'd'], 2), [['a', 'b'], ['c', 'd']]))
|
||||
t(({ eq }) => eq(chunk(['a', 'b', 'c', 'd'], 3), [['a', 'b', 'c'], ['d']]))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,15 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => circular.constructor === Object)
|
||||
t(() => circular.circular === circular)
|
||||
t(() => circular.circular.circular === circular)
|
||||
t(() => circular.circular.circular.circular === circular)
|
||||
t(() => circular.circular.circular.circular.circular === circular)
|
||||
|
||||
/*
|
||||
To understand recursion,
|
||||
one must first understand recursion.
|
||||
*/
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,13 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => typeof concatStr === 'function', 'Should be a function')
|
||||
t(() => concatStr.length === 2, 'Should takes 2 arguments')
|
||||
t(() => concatStr('a', 'b') === 'ab')
|
||||
t(() => concatStr('yolo', 'swag') === 'yoloswag')
|
||||
|
||||
// handle non strings correctly
|
||||
t(() => concatStr(1, 2) === '12')
|
||||
t(() => concatStr(concatStr, concatStr) === String(concatStr).repeat(2))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,9 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => countLeapYears(new Date('0001-12-01')) === 0)
|
||||
t(() => countLeapYears(new Date('1664-08-09')) === 403)
|
||||
t(() => countLeapYears(new Date('2020-01-01')) === 489)
|
||||
t(() => countLeapYears(new Date('2048-12-08')) === 496)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,19 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
const mult2 = (el1, el2) => el1 * el2
|
||||
const add3 = (el1, el2, el3) => el1 + el2 + el3
|
||||
const sub4 = (el1, el2, el3, el4) => el1 - el2 - el3 - el4
|
||||
|
||||
t(({ eq }) => eq(currify(mult2)(2)(5), 10))
|
||||
t(({ eq }) => eq(currify(mult2)(3)(6), 18))
|
||||
t(({ eq }) => eq(currify(mult2)(4)(7), 28))
|
||||
t(({ eq }) => eq(currify(add3)(1)(2)(3), 6))
|
||||
t(({ eq }) => eq(currify(add3)(4)(5)(11), 20))
|
||||
t(({ eq }) => eq(currify(add3)(4)(7)(10), 21))
|
||||
t(({ eq }) => eq(currify(sub4)(4)(7)(10)(30), -43))
|
||||
t(({ eq }) => eq(currify(sub4)(5)(17)(-10)(3), -5))
|
||||
t(({ eq }) => eq(currify(sub4)(3)(72)(-211)(99), 43))
|
||||
t(({ eq }) => eq(currify(sub4)(5)(7)(10)(26), -38))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,96 @@
|
|||
// prettier-ignore
|
||||
const personnel = {
|
||||
lukeSkywalker: { id: 5, pilotingScore: 98, shootingScore: 56, isForceUser: true },
|
||||
sabineWren: { id: 82, pilotingScore: 73, shootingScore: 99, isForceUser: false },
|
||||
zebOrellios: { id: 22, pilotingScore: 20, shootingScore: 59, isForceUser: false },
|
||||
ezraBridger: { id: 15, pilotingScore: 43, shootingScore: 67, isForceUser: true },
|
||||
calebDume: { id: 11, pilotingScore: 71, shootingScore: 85, isForceUser: true },
|
||||
}
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// default values
|
||||
t(({ eq }) => eq(defaultCurry({ http: 403 })({}), { http: 403 }))
|
||||
t(({ eq }) =>
|
||||
eq(defaultCurry({ http: 403, connection: 'close' })({ http: 200 }), {
|
||||
http: 200,
|
||||
connection: 'close',
|
||||
}),
|
||||
)
|
||||
|
||||
// object mutation
|
||||
t(({ eq }) =>
|
||||
eq(defaultCurry(Object.freeze({ http: 403 }))(Object.freeze({ http: 200 })), {
|
||||
http: 200,
|
||||
}),
|
||||
)
|
||||
|
||||
// multiple values
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
defaultCurry({ http: 403, age: 0, connection: 'close' })({
|
||||
http: 200,
|
||||
age: 30,
|
||||
connection: 'keep-alive',
|
||||
content_type: 'text/css',
|
||||
}),
|
||||
{ http: 200, age: 30, connection: 'keep-alive', content_type: 'text/css' },
|
||||
),
|
||||
)
|
||||
|
||||
// map curry
|
||||
t(({ eq }) =>
|
||||
eq(mapCurry(([k, v]) => [`${k}🤙🏼`, `${v}🤙🏼`])({ emoji: 'cool' }), {
|
||||
'emoji🤙🏼': 'cool🤙🏼',
|
||||
}),
|
||||
)
|
||||
|
||||
// reduce curry
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
reduceCurry((acc, [k, v]) => acc.concat(' ', `${k}:${v.id}`))(
|
||||
personnel,
|
||||
'personnel:',
|
||||
),
|
||||
'personnel: lukeSkywalker:5 sabineWren:82 zebOrellios:22 ezraBridger:15 calebDume:11',
|
||||
),
|
||||
)
|
||||
|
||||
// filter curry
|
||||
t(({ eq }) =>
|
||||
eq(filterCurry(([, v]) => v.id > 22)(personnel), {
|
||||
sabineWren: {
|
||||
id: 82,
|
||||
pilotingScore: 73,
|
||||
shootingScore: 99,
|
||||
isForceUser: false,
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
// reduce score
|
||||
t(({ eq }) => eq(reduceScore(personnel, 0), 420))
|
||||
t(({ eq }) => eq(reduceScore(personnel, 420), 840))
|
||||
|
||||
//filter score
|
||||
t(({ eq, ctx }) => eq(filterForce(personnel), ctx.filter))
|
||||
|
||||
// map average
|
||||
t(({ eq, ctx }) => eq(mapAverage(personnel), ctx.total))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
// prettier-ignore
|
||||
export const setup = () => ({
|
||||
filter: {
|
||||
calebDume: { id: 11, isForceUser: true, pilotingScore: 71, shootingScore: 85 },
|
||||
},
|
||||
total: {
|
||||
sabineWren: { id: 82, pilotingScore: 73, shootingScore: 99, isForceUser: false, averageScore: 86 },
|
||||
zebOrellios: { id: 22, pilotingScore: 20, shootingScore: 59, isForceUser: false, averageScore: 39.5 },
|
||||
lukeSkywalker: { id: 5, pilotingScore: 98, shootingScore: 56, isForceUser: true, averageScore: 77 },
|
||||
ezraBridger: { id: 15, pilotingScore: 43, shootingScore: 67, isForceUser: true, averageScore: 55 },
|
||||
calebDume: { id: 11, pilotingScore: 71, shootingScore: 85, isForceUser: true, averageScore: 78 },
|
||||
},
|
||||
})
|
|
@ -0,0 +1,19 @@
|
|||
Math.round = Math.ceil = Math.floor = Math.trunc = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
const nums = [Math.PI, -Math.PI, Math.E, -Math.E, 0]
|
||||
|
||||
t(({ code }) => !/String|['"`]|toFixed|slice/.test(code))
|
||||
t(({ code }) => !code.includes('~'))
|
||||
t(({ code }) => !code.includes('parseInt'))
|
||||
|
||||
t(({ eq }) => eq(nums.map(round), [3, -3, 3, -3, 0]))
|
||||
t(({ eq }) => eq(nums.map(floor), [3, -4, 2, -3, 0]))
|
||||
t(({ eq }) => eq(nums.map(trunc), [3, -3, 2, -2, 0]))
|
||||
t(({ eq }) => eq(nums.map(ceil), [4, -3, 3, -2, 0]))
|
||||
t(({ ctx }) => trunc(0xfffffffff + ctx) === 0xfffffffff + ~~ctx)
|
||||
|
||||
export const setup = () => Math.random() * 10
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,11 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => dayOfTheYear(new Date('0001-01-01')) === 1)
|
||||
t(() => dayOfTheYear(new Date('1664-08-09')) === 222)
|
||||
t(() => dayOfTheYear(new Date('1600-12-31')) === 366)
|
||||
t(() => dayOfTheYear(new Date('2020-06-22')) === 174)
|
||||
t(() => dayOfTheYear(new Date('2048-12-08')) === 343)
|
||||
t(() => dayOfTheYear(new Date('2048-11-08')) === 313)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,58 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
const add = (arr, el) => arr.push(el)
|
||||
|
||||
// it uses the array to better test the leading and trailing edge of the time limit
|
||||
// so if the leading edge is true it will execute the callback
|
||||
// if the trailing edge is true it will execute the callback before returning the array
|
||||
const run = (callback, { delay, count }) =>
|
||||
new Promise((r) => {
|
||||
const arr = []
|
||||
const inter = setInterval(() => callback(arr, 1), delay)
|
||||
setTimeout(() => {
|
||||
clearInterval(inter)
|
||||
r(arr.length)
|
||||
}, delay * count)
|
||||
})
|
||||
|
||||
// test with debounce wait limit inferior to wait time call (how much time we wait to the function be called again)
|
||||
// it works concurrently
|
||||
t(async ({ eq }) =>
|
||||
eq(
|
||||
await Promise.all([
|
||||
run(debounce(add, 5), { delay: 10, count: 5 }),
|
||||
run(debounce(add, 2), { delay: 5, count: 10 }),
|
||||
]),
|
||||
[4, 9],
|
||||
),
|
||||
)
|
||||
// testing with wait limit superior to wait time call
|
||||
// execution on the trailing edge, after wait limit has elapsed
|
||||
t(async ({ eq }) => eq(await run(debounce(add, 10), { delay: 5, count: 5 }), 0))
|
||||
|
||||
// leading edge as false
|
||||
// it works concurrently
|
||||
t(async ({ eq }) =>
|
||||
eq(
|
||||
await Promise.all([
|
||||
run(opDebounce(add, 4), { delay: 2, count: 5 }),
|
||||
run(opDebounce(add, 4), { delay: 2, count: 2 }),
|
||||
]),
|
||||
[0, 0],
|
||||
),
|
||||
)
|
||||
|
||||
// leading edge as true
|
||||
// it works concurrently
|
||||
t(async ({ eq }) =>
|
||||
eq(
|
||||
await Promise.all([
|
||||
run(opDebounce(add, 20, { leading: true }), { delay: 7, count: 3 }),
|
||||
run(opDebounce(add, 10, { leading: true }), { delay: 14, count: 3 }),
|
||||
]),
|
||||
[1, 3],
|
||||
),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,40 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// simple object
|
||||
t(({ eq }) => copyAndCompare(eq, { user: 'mika', age: 37 }))
|
||||
|
||||
// simple array
|
||||
t(({ eq }) => copyAndCompare(eq, [1, 'a']))
|
||||
|
||||
// works with any value type
|
||||
t(({ eq }) => copyAndCompare(eq, [console.log, /hello/]))
|
||||
|
||||
// nesting object
|
||||
t(({ eq }) => copyAndCompare(eq, { a: { b: { c: 1 } } }))
|
||||
|
||||
// nesting array
|
||||
t(({ eq }) => copyAndCompare(eq, [1, [2, [true]]]))
|
||||
|
||||
// mixed nesting
|
||||
t(({ eq }) => copyAndCompare(eq, [{ a: () => {} }, ['b', { b: [3] }]]))
|
||||
|
||||
// undefined value
|
||||
t(({ eq }) => copyAndCompare(eq, { undef: undefined }))
|
||||
|
||||
// check deep freeze (caution: might stuns a target for 4 seconds)
|
||||
t(({ eq }) => {
|
||||
const r = Math.random()
|
||||
const obj = [r, Object.freeze([r, Object.freeze([r])])]
|
||||
const copy = deepCopy(obj)
|
||||
eq(copy, obj)
|
||||
return obj[1][1] !== copy[1][1]
|
||||
})
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
const copyAndCompare = (eq, obj) => {
|
||||
const copy = deepCopy(Object.freeze(obj))
|
||||
eq(copy, obj)
|
||||
return copy !== obj
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
Math.imul = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// * is not allowed for this exercise
|
||||
t(({ code }) => !code.includes('*'))
|
||||
|
||||
t(() => multiply(34, 78) === 2652)
|
||||
t(() => multiply(123, 0) === 0)
|
||||
t(() => multiply(0, -230) === 0)
|
||||
t(() => multiply(0, 0) === 0)
|
||||
t(() => multiply(123, -22) === -2706)
|
||||
t(() => multiply(-22, 123) === -2706)
|
||||
t(() => multiply(-22, -123) === 2706)
|
||||
|
||||
// / is not allowed for this exercise
|
||||
t(({ code }) => !code.includes('/'))
|
||||
|
||||
t(() => divide(34, 78) === 0)
|
||||
t(() => divide(78, 34) === 2)
|
||||
t(() => divide(123, 22) === 5)
|
||||
t(() => divide(123, -22) === -5)
|
||||
t(() => divide(-123, 22) === -5)
|
||||
t(() => divide(-123, -22) === 5)
|
||||
|
||||
// % is not allowed for this exercise
|
||||
t(({ code }) => !code.includes('%'))
|
||||
|
||||
t(() => modulo(34, 78) === 34)
|
||||
t(() => modulo(78, 34) === 10)
|
||||
t(() => modulo(123, 22) === 13)
|
||||
t(() => modulo(123, -22) === 13)
|
||||
t(() => modulo(-123, 22) === -13)
|
||||
t(() => modulo(-123, -22) === -13)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,22 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// escapeStr is declared and of type string
|
||||
t(() => typeof escapeStr === 'string')
|
||||
|
||||
// escapeStr should include the character '
|
||||
t(() => escapeStr.includes("'"))
|
||||
|
||||
// escapeStr should include the character "
|
||||
t(() => escapeStr.includes('"'))
|
||||
|
||||
// escapeStr should include the character `
|
||||
t(() => escapeStr.includes('`'))
|
||||
|
||||
// escapeStr should include the character /
|
||||
t(() => escapeStr.includes('/'))
|
||||
|
||||
// escapeStr should include the character \
|
||||
t(() => escapeStr.includes('\\'))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,38 @@
|
|||
const add4 = '+4'
|
||||
const mul2 = '*2'
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
const result = (expression) =>
|
||||
expression
|
||||
.slice(2)
|
||||
.split(' ')
|
||||
.reduce((total, op) => {
|
||||
if (op === '+4') return total + 4
|
||||
if (op === '*2') return total * 2
|
||||
throw Error(`unknown op ${op}`)
|
||||
}, 1)
|
||||
|
||||
t(
|
||||
({ code }) =>
|
||||
!/[5-9]/g.test(code) && code.includes('add4') && code.includes('mul2'),
|
||||
)
|
||||
|
||||
t(({ eq }) => eq(result(findExpression(8)), 8))
|
||||
t(({ eq }) => eq(result(findExpression(14)), 14))
|
||||
t(({ eq }) => eq(result(findExpression(60)), 60))
|
||||
t(({ eq }) => eq(result(findExpression(100)), 100))
|
||||
t(({ eq }) => eq(result(findExpression(100)), 100))
|
||||
t(({ eq }) => eq(result(findExpression(280)), 280))
|
||||
t(({ eq }) => eq(result(findExpression(110)), 110))
|
||||
t(({ eq }) => eq(result(findExpression(144)), 144))
|
||||
t(({ eq }) => eq(result(findExpression(200)), 200))
|
||||
t(({ eq }) => eq(result(findExpression(104)), 104))
|
||||
|
||||
t(({ eq }) => eq(findExpression(7), undefined))
|
||||
t(({ eq }) => eq(findExpression(63), undefined))
|
||||
t(({ eq }) => eq(findExpression(23), undefined))
|
||||
t(({ eq }) => eq(findExpression(103), undefined))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,63 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(flags({}), { alias: { h: 'help' }, description: '' }))
|
||||
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
flags({
|
||||
invert: 'inverts and object',
|
||||
'convert-map': 'converts the object to an array',
|
||||
assign: 'uses the function assign - assign to target object',
|
||||
}),
|
||||
$a,
|
||||
),
|
||||
)
|
||||
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
flags({
|
||||
invert: 'inverts and object',
|
||||
'convert-map': 'converts the object to an array',
|
||||
assign: 'uses the function assign - assign to target object',
|
||||
help: ['assign', 'invert'],
|
||||
}),
|
||||
$b,
|
||||
),
|
||||
)
|
||||
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
flags({
|
||||
invert: 'inverts and object',
|
||||
'convert-map': 'converts the object to an array',
|
||||
assign: 'uses the function assign - assign to target object',
|
||||
help: ['invert'],
|
||||
}),
|
||||
$c,
|
||||
),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
const $a = {
|
||||
alias: { h: 'help', i: 'invert', c: 'convert-map', a: 'assign' },
|
||||
description: [
|
||||
'-i, --invert: inverts and object',
|
||||
'-c, --convert-map: converts the object to an array',
|
||||
'-a, --assign: uses the function assign - assign to target object',
|
||||
].join('\n'),
|
||||
}
|
||||
|
||||
const $b = {
|
||||
alias: { h: 'help', i: 'invert', c: 'convert-map', a: 'assign' },
|
||||
description: [
|
||||
'-a, --assign: uses the function assign - assign to target object',
|
||||
'-i, --invert: inverts and object',
|
||||
].join('\n'),
|
||||
}
|
||||
|
||||
const $c = {
|
||||
alias: { h: 'help', i: 'invert', c: 'convert-map', a: 'assign' },
|
||||
description: '-i, --invert: inverts and object',
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
Array.prototype.flat = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(flat([1]), [1]))
|
||||
t(({ eq }) => eq(flat([1, [2]]), [1, 2]))
|
||||
t(({ eq }) => eq(flat([1, [2, [3]]]), [1, 2, [3]]))
|
||||
t(({ eq }) => eq(flat([1, [2, [3], [4, [5]]]], 2), [1, 2, 3, 4, [5]]))
|
||||
t(({ eq }) => eq(flat([1, [2, [3], [4, [5]]]], 3), [1, 2, 3, 4, 5]))
|
||||
t(({ eq }) => eq(flat([1, [2, [3], [4, [5]]]], Infinity), [1, 2, 3, 4, 5]))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,51 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
const sub32 = (el) => el - 32
|
||||
const mult5 = (el) => el * 5
|
||||
const div9 = (el) => el / 9
|
||||
const roundDown = (el) => Math.floor(el)
|
||||
|
||||
const square = (nbr) => nbr * nbr
|
||||
const add2 = (el) => el + 2
|
||||
const mult2 = (el) => el * 2
|
||||
|
||||
const addAll = (...el) =>
|
||||
el.length === 1 ? el[0] : el[0] + addAll(...el.slice(1))
|
||||
|
||||
export const setup = () => {
|
||||
const farenheitToCelsius = flow(sub32, mult5, div9, roundDown)
|
||||
const add2Mult2Square = flow(add2, mult2, square)
|
||||
const addAllThenConvertToCelsius = flow(addAll, farenheitToCelsius)
|
||||
|
||||
return { farenheitToCelsius, add2Mult2Square, addAllThenConvertToCelsius }
|
||||
}
|
||||
|
||||
//Farenheit to Celsius
|
||||
|
||||
t(({ eq, ctx }) => eq(ctx.farenheitToCelsius(32), 0))
|
||||
t(({ eq, ctx }) => eq(ctx.farenheitToCelsius(0), -18))
|
||||
t(({ eq, ctx }) => eq(ctx.farenheitToCelsius(40), 4))
|
||||
t(({ eq, ctx }) => eq(ctx.farenheitToCelsius(50), 10))
|
||||
t(({ eq, ctx }) => eq(ctx.farenheitToCelsius(60), 15))
|
||||
t(({ eq, ctx }) => eq(ctx.farenheitToCelsius(100), 37))
|
||||
|
||||
// add2Mult2Square
|
||||
|
||||
t(({ eq, ctx }) => eq(ctx.add2Mult2Square(32), 4624))
|
||||
t(({ eq, ctx }) => eq(ctx.add2Mult2Square(0), 16))
|
||||
t(({ eq, ctx }) => eq(ctx.add2Mult2Square(40), 7056))
|
||||
t(({ eq, ctx }) => eq(ctx.add2Mult2Square(50), 10816))
|
||||
t(({ eq, ctx }) => eq(ctx.add2Mult2Square(60), 15376))
|
||||
t(({ eq, ctx }) => eq(ctx.add2Mult2Square(-100), 38416))
|
||||
|
||||
// addAllThenConvertToCelsius
|
||||
|
||||
t(({ eq, ctx }) => eq(ctx.addAllThenConvertToCelsius(20, 5, 6, 1), 0))
|
||||
t(({ eq, ctx }) => eq(ctx.addAllThenConvertToCelsius(-10, -10, 20), -18))
|
||||
t(({ eq, ctx }) => eq(ctx.addAllThenConvertToCelsius(10, 5, 5, 10, 5, 5), 4))
|
||||
t(({ eq, ctx }) => eq(ctx.addAllThenConvertToCelsius(25, 5, 20), 10))
|
||||
t(({ eq, ctx }) => eq(ctx.addAllThenConvertToCelsius(30, 30), 15))
|
||||
t(({ eq, ctx }) => eq(ctx.addAllThenConvertToCelsius(99, 1), 37))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,80 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// simple numbers
|
||||
t(({ eq }) => eq(fusion({ nbr: 12 }, { nbr: 23 }).nbr, 35))
|
||||
|
||||
// handle 0
|
||||
t(({ eq }) => eq(fusion({ nbr: 0 }, { nbr: 23 }).nbr, 23))
|
||||
t(({ eq }) => eq(fusion({ nbr: 23 }, { nbr: 0 }).nbr, 23))
|
||||
|
||||
// multiply numbers
|
||||
t(({ eq }) =>
|
||||
eq(fusion({ a: 12, b: 2, c: 43 }, { a: 23, b: 2 }), { a: 35, b: 4, c: 43 }),
|
||||
)
|
||||
|
||||
// simple string
|
||||
t(({ eq }) => eq(fusion({ str: 'hello' }, { str: 'there' }).str, 'hello there'))
|
||||
|
||||
// handle empty strings
|
||||
t(({ eq }) => eq(fusion({ str: 'hello' }, { str: '' }).str, 'hello '))
|
||||
|
||||
// multiple strings
|
||||
t(({ eq }) =>
|
||||
eq(fusion({ a: 'A', b: 'B', c: 'C' }, { a: 'B', b: 'C' }), {
|
||||
a: 'A B',
|
||||
b: 'B C',
|
||||
c: 'C',
|
||||
}),
|
||||
)
|
||||
|
||||
// simple arrays
|
||||
t(({ eq }) => eq(fusion({ arr: [1, '2'] }, { arr: [2] }).arr, [1, '2', 2]))
|
||||
|
||||
// multiple arrays
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
fusion(
|
||||
{ arr: [], arr1: [1] },
|
||||
{ arr: [12, 3], arr1: [2, 3], arr2: ['2', '1'] },
|
||||
),
|
||||
{ arr: [12, 3], arr1: [1, 2, 3], arr2: ['2', '1'] },
|
||||
),
|
||||
)
|
||||
|
||||
// different matching
|
||||
t(({ eq }) => eq(fusion({ a: { b: 1 } }, { a: 1 }).a, 1))
|
||||
t(({ eq }) => eq(fusion({ a: 1 }, { a: { b: 1 } }).a, { b: 1 }))
|
||||
t(({ eq }) => eq(fusion({ a: [1, 2] }, { a: 1 }).a, 1))
|
||||
t(({ eq }) => eq(fusion({ a: 'str' }, { a: 1 }).a, 1))
|
||||
|
||||
// deep nested objects
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
fusion(
|
||||
{ a: { b: [1, 2], c: { d: 2 } } },
|
||||
{ a: { b: [0, 2, 1], c: { d: 23 } } },
|
||||
),
|
||||
{ a: { b: [1, 2, 0, 2, 1], c: { d: 25 } } },
|
||||
),
|
||||
)
|
||||
|
||||
// object mutability
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
fusion(Object.freeze({ a: { b: 1 } }), Object.freeze({ a: { b: 2 } })).a.b,
|
||||
3,
|
||||
),
|
||||
)
|
||||
|
||||
// other types
|
||||
t(({ eq }) => eq(fusion({ reg: /\w/ }, { reg: /\S/ }).reg, /\S/))
|
||||
t(({ eq }) => {
|
||||
const set = new Set([1, 2, 3])
|
||||
return eq(fusion({ a: 1, set: new Set([4, 5, 6]) }, { a: 1, set }), {
|
||||
a: 2,
|
||||
set,
|
||||
})
|
||||
})
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,15 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// handle simple array
|
||||
t(() => getLength([2, 42]) === 2)
|
||||
|
||||
// handle mixed array
|
||||
t(() => getLength(['pouet', 4, true]) === 3)
|
||||
|
||||
t(() => getLength(Array(100)) === 100) // handle holey array
|
||||
t(() => getLength('salut') === 5) // handle strings
|
||||
t(() => getLength([]) === 0) // handle empty arrays
|
||||
t(() => getLength('') === 0) // handle empty strings
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,19 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// work with simple key / values
|
||||
t(() => get({ key: 'value' }, 'key') === 'value')
|
||||
|
||||
// work with nested objects
|
||||
t(() => get({ nested: { key: 'value' } }, 'nested.key') === 'value')
|
||||
|
||||
// return undefined without error if the value do not exist
|
||||
t(() => get({ key: 'value' }, 'nx') === undefined)
|
||||
t(() => get({ nested: { key: 'value' } }, 'nested.nx') === undefined)
|
||||
t(() => get({ nested: { key: 'value' } }, 'nx.nx') === undefined)
|
||||
|
||||
// work with nested arrays too
|
||||
t(() => get({ a: [{ b: t }] }, 'a.0.b') === t)
|
||||
t(() => get({ a: [{ b: t }] }, 'a.0.b.toString') === t.toString)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,50 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(getURL(dataSet), $getURL))
|
||||
t(({ eq }) => eq(greedyQuery(dataSet), $greedyQuery))
|
||||
t(({ eq }) => eq(notSoGreedy(dataSet), $notSoGreedy))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
const dataSet = `qqq http:// qqqq q qqqqq https://something.com/hello qqqqqqq qhttp://example.com/hello?you=something&something=you qq 233.123.12.234 qw w wq wqw wqw ijnjjnfapsdbjnkfsdiqw klfsdjn fs fsd https://devdocs.io/javascript/global_objects/object/fromentries njnkfsdjnk sfdjn fsp fd192.168.1.123:8080 https://devdocs.io/javascript/global_objects/regexp/@@split
|
||||
htpp://wrong/url hello %$& wf* ][½¬ http://correct/url?correct=yes è[}£§ https://nan-academy.github.io/js-training/?page=editor#data.nested 255.256.1233.2
|
||||
ssages has become an accepted http://hummm/how?how=come&same=[123,21]&you=nextperson&id=123312&next=123DSAD&ok=true¬Ok=true part of many cultures, as happened earlier with emailing. htt://[1] This makes texting a quick and http://www.example.com/mypage.html?crcat=test&crsource=test&crkw=buy-a-loteasy way to communicate 255.256.2 with friends, family and colleagues, including 255.256.555.2 in contexts where a call would be when one knows the other person is busy 192.169.1.23 with family or work activities).; 172.01.123.254:1234
|
||||
for example, to order products or 10.1.23.7 http://www_example.com/
|
||||
services fromhttps://regex-performance.github.io/exercises.html
|
||||
this permits communication even between busy individuals255.253.123.2:8000 https: // . Text messages can also http:// be used to http://example.com/path?name=Branch&products=[Journeys,Email,Universal%20Ads]interact with automated systems,https:// regex -performance.github.io/ exercises.html172.01.123.999:1234
|
||||
https//nan-academy.github.io/js-training/?page=editor#data.nested impolite or inappropriate (e.g., calling very late at night orhttp://localhost/exercises
|
||||
https://192.168.1.123?something=nothing&pro=[23] htts:/nan-academy.github.io/js-training?b=123&a=123/?page=editor#data.nested Like e-mail and voicemail and unlike calls https://www.notherExample.com/catalog.asp?itemid=232&template=fresh&crcat=ppc&crsource=google&crkw=buy-a-lot&id=3&qwe=ty (in which the caller hopes to speak directly with the recipient),
|
||||
http://www.example.com/catalog.asp?itemid=232&template=fresh&crcat=ppc&crsource=google&crkw=buy-a-lot texting does not require the caller and recipient to both be free at the same moment0.0.0.0`
|
||||
|
||||
const $greedyQuery = [
|
||||
'http://hummm/how?how=come&same=[123,21]&you=nextperson&id=123312&next=123DSAD&ok=true¬Ok=true',
|
||||
'http://www.example.com/mypage.html?crcat=test&crsource=test&crkw=buy-a-loteasy',
|
||||
'https://www.notherExample.com/catalog.asp?itemid=232&template=fresh&crcat=ppc&crsource=google&crkw=buy-a-lot&id=3&qwe=ty',
|
||||
'http://www.example.com/catalog.asp?itemid=232&template=fresh&crcat=ppc&crsource=google&crkw=buy-a-lot',
|
||||
]
|
||||
|
||||
const $notSoGreedy = [
|
||||
'http://example.com/hello?you=something&something=you',
|
||||
'http://www.example.com/mypage.html?crcat=test&crsource=test&crkw=buy-a-loteasy',
|
||||
'http://example.com/path?name=Branch&products=[Journeys,Email,Universal%20Ads]interact',
|
||||
'https://192.168.1.123?something=nothing&pro=[23]',
|
||||
]
|
||||
|
||||
const $getURL = [
|
||||
'https://something.com/hello',
|
||||
'http://example.com/hello?you=something&something=you',
|
||||
'https://devdocs.io/javascript/global_objects/object/fromentries',
|
||||
'https://devdocs.io/javascript/global_objects/regexp/@@split',
|
||||
'http://correct/url?correct=yes',
|
||||
'https://nan-academy.github.io/js-training/?page=editor#data.nested',
|
||||
'http://hummm/how?how=come&same=[123,21]&you=nextperson&id=123312&next=123DSAD&ok=true¬Ok=true',
|
||||
'http://www.example.com/mypage.html?crcat=test&crsource=test&crkw=buy-a-loteasy',
|
||||
'http://www_example.com/',
|
||||
'https://regex-performance.github.io/exercises.html',
|
||||
'http://example.com/path?name=Branch&products=[Journeys,Email,Universal%20Ads]interact',
|
||||
'http://localhost/exercises',
|
||||
'https://192.168.1.123?something=nothing&pro=[23]',
|
||||
'https://www.notherExample.com/catalog.asp?itemid=232&template=fresh&crcat=ppc&crsource=google&crkw=buy-a-lot&id=3&qwe=ty',
|
||||
'http://www.example.com/catalog.asp?itemid=232&template=fresh&crcat=ppc&crsource=google&crkw=buy-a-lot',
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
t(({ eq }) =>
|
||||
eq(groupPrice('The price of the cereals is $4.00.'), [['$4.00', '4', '00']]),
|
||||
)
|
||||
t(({ eq }) =>
|
||||
eq(groupPrice('the total is USD19.98'), [['USD19.98', '19', '98']]),
|
||||
)
|
||||
t(({ eq }) =>
|
||||
eq(groupPrice('excuse me sir it is missing $0.45'), [['$0.45', '0', '45']]),
|
||||
)
|
||||
t(({ eq }) =>
|
||||
eq(groupPrice('excuse me sir here is your change $99.20'), [
|
||||
['$99.20', '99', '20'],
|
||||
]),
|
||||
)
|
||||
t(({ eq }) => eq(groupPrice('this, 0.32, is not a match'), []))
|
||||
t(({ eq }) =>
|
||||
eq(groupPrice('product one its $9.98 and the second one its $10.20'), [
|
||||
['$9.98', '9', '98'],
|
||||
['$10.20', '10', '20'],
|
||||
]),
|
||||
)
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,54 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// create specialized functions
|
||||
t(({ ctx }) => {
|
||||
ctx.isFrench = hasCity('France', [
|
||||
'Bordeaux',
|
||||
'Paris',
|
||||
'Lille',
|
||||
'Lyon',
|
||||
'Marseille',
|
||||
'Saint-Étienne',
|
||||
])
|
||||
ctx.isUS = hasCity('the US', [
|
||||
'New York',
|
||||
'Chicago',
|
||||
'San Francisco',
|
||||
'Washington DC',
|
||||
'Los Angeles',
|
||||
])
|
||||
ctx.isChinese = hasCity('China', [
|
||||
'Beijing',
|
||||
'Shanghai',
|
||||
'Wuhan',
|
||||
'Shenzhen',
|
||||
'Tianjin',
|
||||
'Chengdu',
|
||||
])
|
||||
return true
|
||||
})
|
||||
|
||||
t(({ eq, ctx }) => eq(ctx.isChinese('Beijing'), 'Beijing is a city from China'))
|
||||
t(({ eq, ctx }) => eq(ctx.isFrench('Lille'), 'Lille is a city from France'))
|
||||
t(({ eq, ctx }) => eq(ctx.isUS('New York'), 'New York is a city from the US'))
|
||||
t(({ eq, ctx }) => eq(ctx.isChinese('Tokyo'), 'Tokyo is not a city from China'))
|
||||
t(({ eq, ctx }) => eq(ctx.isFrench('Paris'), 'Paris is a city from France'))
|
||||
t(({ eq, ctx }) => eq(ctx.isUS('Abidjan'), 'Abidjan is not a city from the US'))
|
||||
t(({ eq, ctx }) => eq(ctx.isChinese('Seul'), 'Seul is not a city from China'))
|
||||
t(({ eq, ctx }) => eq(ctx.isUS(''), ' is not a city from the US'))
|
||||
t(({ eq, ctx }) => eq(ctx.isChinese('Wuhan'), 'Wuhan is a city from China'))
|
||||
|
||||
t(({ eq, ctx }) =>
|
||||
eq(ctx.isFrench('Lisbon'), 'Lisbon is not a city from France'),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) =>
|
||||
eq(ctx.isUS('Los Angeles'), 'Los Angeles is a city from the US'),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) =>
|
||||
eq(ctx.isFrench('Chengdu'), 'Chengdu is not a city from France'),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,22 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// id is declared and is a function
|
||||
t(() => typeof id === 'function')
|
||||
|
||||
// id take 1 argument
|
||||
t(() => id.length === 1)
|
||||
|
||||
// id return numbers back
|
||||
t(() => id(5) === 5)
|
||||
|
||||
// id return strings back
|
||||
t(() => id('pouet') === 'pouet')
|
||||
|
||||
// id return itself, why not
|
||||
t(() => id(id) === id)
|
||||
|
||||
// id return anything really
|
||||
t((_) => id(_) === _)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,30 @@
|
|||
Array.prototype.indexOf = undefined
|
||||
Array.prototype.lastIndexOf = undefined
|
||||
Array.prototype.includes = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
const bigArray = [...Array(999).keys(), ...Array(999).keys()]
|
||||
|
||||
t(() => indexOf([1, 2, 3, 4, 5, 4, 3, 2, 1], 2) === 1)
|
||||
t(() => indexOf([0, 0, t, t], t) === 2)
|
||||
t(() => indexOf([t, 0, 0, t], t, 1) === 3)
|
||||
t(() => indexOf([t, 0, 0, t], t, 0) === 0)
|
||||
t(({ ctx }) => indexOf(bigArray, ctx.rn) === ctx.rn)
|
||||
t(({ ctx }) => indexOf(bigArray, {}) === -1)
|
||||
|
||||
t(() => lastIndexOf([1, 2, 3, 4, 5, 4, 3, 2, 1], 2) === 7)
|
||||
t(() => lastIndexOf([0, 0, t, t], t) === 3)
|
||||
t(() => lastIndexOf([0, 0, t, t], t, 3) === 3)
|
||||
t(() => lastIndexOf([t, 0, 0, t], t, 2) === 0)
|
||||
t(({ ctx }) => lastIndexOf(bigArray, ctx.rn) === ctx.rn + 999)
|
||||
t(({ ctx }) => lastIndexOf(bigArray, {}) === -1)
|
||||
|
||||
t(() => includes([1, 2, 3, 4, 5, 4, 3, 2, 1], 2))
|
||||
t(() => includes([0, 0, t, t], t))
|
||||
t(({ ctx }) => includes(bigArray, ctx.rn))
|
||||
t(({ ctx }) => !includes(bigArray, {}))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = () => ({ rn: Math.trunc(Math.random() * 999) })
|
|
@ -0,0 +1,32 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// It works with a single property
|
||||
t(({ eq }) => eq(invert({ language: 'english' }), { english: 'language' }))
|
||||
|
||||
// It works with multiple properties
|
||||
t(({ eq }) =>
|
||||
eq(invert({ firstName: 'John', lastName: 'Doe', age: 32 }), {
|
||||
John: 'firstName',
|
||||
Doe: 'lastName',
|
||||
32: 'age',
|
||||
}),
|
||||
)
|
||||
|
||||
// Last similar value should override the others
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
invert({ brand: 'ford', motor: 'v8', year: 2000, fast: true, eco: true }),
|
||||
{
|
||||
ford: 'brand',
|
||||
v8: 'motor',
|
||||
2000: 'year',
|
||||
true: 'eco',
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
// It should ignore properties from the prototype chain
|
||||
t(({ eq }) => eq(invert({ f: 5, __proto__: { d: 6 } }), { 5: 'f' }))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,14 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(ionOut('attention, direction'), ['attent', 'direct']))
|
||||
t(({ eq }) => eq(ionOut('promotion, provision'), ['promot']))
|
||||
t(({ eq }) => eq(ionOut('transfusion'), []))
|
||||
t(({ eq }) =>
|
||||
eq(ionOut(' 1st position is the vision of the 2nd position'), [
|
||||
'posit',
|
||||
'posit',
|
||||
]),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,58 @@
|
|||
const is = {}
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// your functions are all tested against all these values:
|
||||
export const setup = () => [
|
||||
0,
|
||||
NaN,
|
||||
true,
|
||||
'',
|
||||
'💩',
|
||||
undefined,
|
||||
t,
|
||||
[],
|
||||
{},
|
||||
[1, Array(1), [], 2],
|
||||
{ length: 10 },
|
||||
Object.create(null),
|
||||
null,
|
||||
console.log,
|
||||
void 0,
|
||||
]
|
||||
|
||||
const match = ({ eq, ctx }, fun, values) => eq(ctx.filter(fun), values)
|
||||
|
||||
// the array of value here is the ones that your function should
|
||||
// return true too, while returning false to every others.
|
||||
t((_) => match(_, is.num, [0, NaN]))
|
||||
t((_) => match(_, is.nan, [NaN]))
|
||||
t((_) => match(_, is.str, ['', '💩']))
|
||||
t((_) => match(_, is.bool, [true]))
|
||||
t((_) => match(_, is.undef, [undefined, undefined]))
|
||||
t((_) => match(_, is.arr, [[], [1, Array(1), [], 2]]))
|
||||
t((_) => match(_, is.obj, [{}, { length: 10 }, Object.create(null)]))
|
||||
t((_) => match(_, is.fun, [t, console.log]))
|
||||
t((_) => match(_, is.falsy, [0, NaN, '', undefined, null, void 0]))
|
||||
|
||||
// is.def
|
||||
t(({ ctx }) => !ctx.filter(is.def).includes(undefined))
|
||||
t(({ ctx }) => ctx.filter(is.def).length === ctx.length - 2)
|
||||
|
||||
// is.truthy
|
||||
t((_) =>
|
||||
match(_, is.truthy, [
|
||||
true,
|
||||
'💩',
|
||||
t,
|
||||
[],
|
||||
{},
|
||||
[1, Array(1), [], 2],
|
||||
{ length: 10 },
|
||||
Object.create(null),
|
||||
console.log,
|
||||
]),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,30 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => normal.test('hi'))
|
||||
t(() => normal.test('higher'))
|
||||
t(() => !normal.test('likelihood'))
|
||||
t(() => !normal.test('Hi'))
|
||||
t(() => normal.test('I love sushi'))
|
||||
|
||||
t(() => begin.test('hi'))
|
||||
t(() => begin.test('higher'))
|
||||
t(() => begin.test('hired'))
|
||||
t(() => !begin.test('likelihood'))
|
||||
t(() => !begin.test('Hi'))
|
||||
t(() => !begin.test('I love sushi'))
|
||||
|
||||
t(() => end.test('hi'))
|
||||
t(() => !end.test('higher'))
|
||||
t(() => !end.test('likelihood'))
|
||||
t(() => !end.test('Hi'))
|
||||
t(() => end.test('I love sushi'))
|
||||
|
||||
t(() => beginEnd.test('hi'))
|
||||
t(() => !beginEnd.test('hired kimchi'))
|
||||
t(() => !beginEnd.test('higher'))
|
||||
t(() => !beginEnd.test('likelihood'))
|
||||
t(() => !beginEnd.test('Hi'))
|
||||
t(() => !beginEnd.test('I love sushi'))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,26 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => cutFirst('abcdef') === 'cdef')
|
||||
t(() => cutFirst('a') === '')
|
||||
|
||||
t(() => cutLast('abcdef') === 'abcd')
|
||||
t(() => cutLast('a') === '')
|
||||
|
||||
t(() => cutFirstLast('abcdef') === 'cd')
|
||||
t(() => cutFirstLast('af') === '')
|
||||
t(() => cutFirstLast('afd') === '')
|
||||
t(() => cutFirstLast('yoafdyo') === 'afd')
|
||||
|
||||
t(() => keepFirst('abcdef') === 'ab')
|
||||
t(() => keepFirst('a') === 'a')
|
||||
|
||||
t(() => keepLast('abcdef') === 'ef')
|
||||
t(() => keepLast('a') === 'a')
|
||||
|
||||
t(() => keepFirstLast('abcdef') === 'abef')
|
||||
t(() => keepFirstLast('af') === 'af')
|
||||
t(() => keepFirstLast('afd') === 'afd')
|
||||
t(() => keepFirstLast('yoafdyo') === 'yoyo')
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,18 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(last([2, 42]), 42)) // Oh
|
||||
t(({ eq }) => eq(last(['pouet', 4, true]), true))
|
||||
t(({ eq }) => eq(last([last]), last)) // I wanna be last, yeah
|
||||
t(({ eq }) => eq(last('salut'), 't')) // Baby let me be your last
|
||||
t(({ eq }) => eq(last([]), undefined)) // Your last first kiss
|
||||
t(({ eq }) => eq(first([2, 42]), 2))
|
||||
t(({ eq }) => eq(first(['pouet', 4, true]), 'pouet'))
|
||||
t(({ eq }) => eq(first([first]), first))
|
||||
t(({ eq }) => eq(first('salut'), 's'))
|
||||
t(({ eq }) => eq(first([]), undefined))
|
||||
t(({ eq }) => eq(kiss([1, 2, 3, 4, 5, 6]), [6, 1]))
|
||||
t(({ eq }) => eq(kiss([eq, kiss, first]), [first, eq]))
|
||||
t(({ eq }) => eq(kiss([]), [undefined, undefined]))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,13 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) =>
|
||||
eq(letterSpaceNumber('He is 8 or 9 years old, not 10.'), ['s 8', 'r 9']),
|
||||
)
|
||||
t(({ eq }) => eq(letterSpaceNumber('I like 7up.'), []))
|
||||
t(({ eq }) => eq(letterSpaceNumber("It's 20 past 3"), ['t 3']))
|
||||
t(({ eq }) => eq(letterSpaceNumber('example 1, example 2'), ['e 1', 'e 2']))
|
||||
t(({ eq }) => eq(letterSpaceNumber(''), []))
|
||||
t(({ eq }) => eq(letterSpaceNumber('Definitely 9.'), ['y 9']))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,51 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
//monkey patch of every
|
||||
|
||||
export const setup = () => {
|
||||
const everyCalls = []
|
||||
const _every = Array.prototype.every
|
||||
Array.prototype.every = function () {
|
||||
everyCalls.push(this)
|
||||
return _every.apply(this, arguments)
|
||||
}
|
||||
|
||||
const someCalls = []
|
||||
const _some = Array.prototype.some
|
||||
Array.prototype.some = function () {
|
||||
someCalls.push(this)
|
||||
return _some.apply(this, arguments)
|
||||
}
|
||||
return { everyCalls, someCalls }
|
||||
}
|
||||
|
||||
let arr1 = ['fill', 'carbon', 'chart', 'glare', 'express']
|
||||
let arr2 = ['double', 'afford', 'coalition', 'reaction', 'persist']
|
||||
let arr3 = ['leak', 'talk', 'bite', 'slip', 'free']
|
||||
let arr4 = ['fixture', 'opponent', 'coincide', 'residential', 'relaxation']
|
||||
|
||||
t(({ eq }) => eq(longWords(arr1), false))
|
||||
t(({ eq, ctx }) => eq(ctx.everyCalls[ctx.everyCalls.length - 1], arr1))
|
||||
t(({ eq }) => eq(longWords(arr2), true))
|
||||
t(({ eq, ctx }) => eq(ctx.everyCalls[ctx.everyCalls.length - 1], arr2))
|
||||
t(({ eq }) => eq(longWords(arr3), false))
|
||||
t(({ eq, ctx }) => eq(ctx.everyCalls[ctx.everyCalls.length - 1], arr3))
|
||||
t(({ eq }) => eq(longWords(arr4), true))
|
||||
t(({ eq, ctx }) => eq(ctx.everyCalls[ctx.everyCalls.length - 1], arr4))
|
||||
|
||||
t(({ eq }) => eq(oneLongWord(arr1), false))
|
||||
t(({ eq, ctx }) => eq(ctx.someCalls[ctx.someCalls.length - 1], arr1))
|
||||
t(({ eq }) => eq(oneLongWord(arr2), false))
|
||||
t(({ eq, ctx }) => eq(ctx.someCalls[ctx.someCalls.length - 1], arr2))
|
||||
t(({ eq }) => eq(oneLongWord(arr3), false))
|
||||
t(({ eq, ctx }) => eq(ctx.someCalls[ctx.someCalls.length - 1], arr3))
|
||||
t(({ eq }) => eq(oneLongWord(arr4), true))
|
||||
t(({ eq, ctx }) => eq(ctx.someCalls[ctx.someCalls.length - 1], arr4))
|
||||
|
||||
t(({ eq }) => eq(noLongWords(arr1), false))
|
||||
t(({ eq }) => eq(noLongWords(arr2), false))
|
||||
t(({ eq }) => eq(noLongWords(arr3), true))
|
||||
t(({ eq }) => eq(noLongWords(arr4), false))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,136 @@
|
|||
// small database with nutrition facts, per 100 grams
|
||||
// prettier-ignore
|
||||
const nutritionDB = {
|
||||
tomato: { calories: 18, protein: 0.9, carbs: 3.9, sugar: 2.6, fiber: 1.2, fat: 0.2 },
|
||||
vinegar: { calories: 20, protein: 0.04, carbs: 0.6, sugar: 0.4, fiber: 0, fat: 0 },
|
||||
oil: { calories: 48, protein: 0, carbs: 0, sugar: 123, fiber: 0, fat: 151 },
|
||||
onion: { calories: 0, protein: 1, carbs: 9, sugar: 0, fiber: 0, fat: 0 },
|
||||
garlic: { calories: 149, protein: 6.4, carbs: 33, sugar: 1, fiber: 2.1, fat: 0.5 },
|
||||
paprika: { calories: 282, protein: 14.14, carbs: 53.99, sugar: 1, fiber: 0, fat: 12.89 },
|
||||
sugar: { calories: 387, protein: 0, carbs: 100, sugar: 100, fiber: 0, fat: 0 },
|
||||
orange: { calories: 49, protein: 0.9, carbs: 13, sugar: 9, fiber: 0.2, fat: 0.1 },
|
||||
}
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// filter entries
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
filterEntries(ctx.groceriesCart1, ([, v]) => v < 300),
|
||||
{ onion: 230, garlic: 220 },
|
||||
),
|
||||
)
|
||||
|
||||
// map entries
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
mapEntries(ctx.groceriesCart1, ([k, v]) => [
|
||||
v > 250 ? `✔️${k}` : `❌${k}`,
|
||||
v - 250,
|
||||
]),
|
||||
{
|
||||
'✔️oil': 250,
|
||||
'❌onion': -20,
|
||||
'❌garlic': -30,
|
||||
'✔️paprika': 230,
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
// filter and map
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
mapEntries(
|
||||
filterEntries(ctx.groceriesCart1, ([k, v]) => k === 'onion'),
|
||||
([k, v]) => [`✔️${k}`, v - 100],
|
||||
),
|
||||
{ '✔️onion': 130 },
|
||||
),
|
||||
)
|
||||
|
||||
// reduce entries
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
reduceEntries(ctx.groceriesCart1, (acc, [k, v]) => acc + k + v, ''),
|
||||
'oil500onion230garlic220paprika480',
|
||||
),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) => eq(lowCarbs(ctx.groceriesCart1), { oil: 500, onion: 230 }))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(lowCarbs(ctx.groceriesCart2), { vinegar: 120, tomato: 700 }),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) => eq(totalCalories(ctx.groceriesCart1), 1921.4))
|
||||
t(({ eq, ctx }) => eq(totalCalories(ctx.groceriesCart2), 370.5))
|
||||
|
||||
t(({ eq, ctx }) => eq(cartTotal(ctx.groceriesCart1), ctx.total1))
|
||||
t(({ eq, ctx }) => eq(cartTotal(ctx.groceriesCart2), ctx.total2))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = () => ({
|
||||
groceriesCart1: { oil: 500, onion: 230, garlic: 220, paprika: 480 },
|
||||
groceriesCart2: { tomato: 700, vinegar: 120, orange: 450 },
|
||||
total1: {
|
||||
oil: {
|
||||
calories: 240,
|
||||
protein: 0,
|
||||
carbs: 0,
|
||||
sugar: 615,
|
||||
fiber: 0,
|
||||
fat: 755,
|
||||
},
|
||||
onion: {
|
||||
calories: 0,
|
||||
protein: 2.3,
|
||||
carbs: 20.7,
|
||||
sugar: 0,
|
||||
fiber: 0,
|
||||
fat: 0,
|
||||
},
|
||||
garlic: {
|
||||
calories: 327.8,
|
||||
protein: 14.08,
|
||||
carbs: 72.6,
|
||||
sugar: 2.2,
|
||||
fiber: 4.62,
|
||||
fat: 1.1,
|
||||
},
|
||||
paprika: {
|
||||
calories: 1353.6,
|
||||
protein: 67.872,
|
||||
carbs: 259.152,
|
||||
sugar: 4.8,
|
||||
fiber: 0,
|
||||
fat: 61.872,
|
||||
},
|
||||
},
|
||||
total2: {
|
||||
orange: {
|
||||
calories: 220.5,
|
||||
carbs: 58.5,
|
||||
fat: 0.45,
|
||||
fiber: 0.9,
|
||||
protein: 4.05,
|
||||
sugar: 40.5,
|
||||
},
|
||||
tomato: {
|
||||
calories: 126,
|
||||
carbs: 27.3,
|
||||
fat: 1.4,
|
||||
fiber: 8.4,
|
||||
protein: 6.3,
|
||||
sugar: 18.2,
|
||||
},
|
||||
vinegar: {
|
||||
calories: 24,
|
||||
carbs: 0.72,
|
||||
fat: 0,
|
||||
fiber: 0,
|
||||
protein: 0.048,
|
||||
sugar: 0.48,
|
||||
},
|
||||
},
|
||||
})
|
|
@ -0,0 +1,123 @@
|
|||
// small database with nutrition facts, per 100 grams
|
||||
// prettier-ignore
|
||||
const nutritionDB = {
|
||||
tomato: { calories: 18, protein: 0.9, carbs: 3.9, sugar: 2.6, fiber: 1.2, fat: 0.2 },
|
||||
vinegar: { calories: 20, protein: 0.04, carbs: 0.6, sugar: 0.4, fiber: 0, fat: 0 },
|
||||
oil: { calories: 48, protein: 0, carbs: 0, sugar: 123, fiber: 0, fat: 151 },
|
||||
onion: { calories: 0, protein: 1, carbs: 9, sugar: 0, fiber: 0, fat: 0 },
|
||||
garlic: { calories: 149, protein: 6.4, carbs: 33, sugar: 1, fiber: 2.1, fat: 0.5 },
|
||||
paprika: { calories: 282, protein: 14.14, carbs: 53.99, sugar: 1, fiber: 0, fat: 12.89 },
|
||||
sugar: { calories: 387, protein: 0, carbs: 100, sugar: 100, fiber: 0, fat: 0 },
|
||||
orange: { calories: 49, protein: 0.9, carbs: 13, sugar: 12, fiber: 0.2, fat: 0.1 },
|
||||
}
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// filter keys
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
filterKeys(ctx.cart, (k) => k.length <= 6),
|
||||
ctx.filtered,
|
||||
),
|
||||
)
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
filterKeys(ctx.cart, (k) => /onion/.test(k)),
|
||||
{ onion: 200 },
|
||||
),
|
||||
)
|
||||
|
||||
// map keys
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
mapKeys(ctx.cart, (k) => `✔️${k}`),
|
||||
ctx.mapped,
|
||||
),
|
||||
)
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
mapKeys(
|
||||
filterKeys(ctx.cart, (k) => k === 'onion'),
|
||||
(k) => (k = 'orange'),
|
||||
),
|
||||
{ orange: 200 },
|
||||
),
|
||||
)
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
mapKeys(
|
||||
filterKeys(nutritionDB, (k) => k === 'tomato'),
|
||||
(k) => `${k}DB`,
|
||||
),
|
||||
ctx.combo,
|
||||
),
|
||||
)
|
||||
|
||||
// reduce keys
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
reduceKeys(ctx.cart, (acc, cr) => acc.concat(', ', cr)),
|
||||
'vinegar, sugar, oil, onion, garlic, paprika',
|
||||
),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
reduceKeys(ctx.cart, (acc, cr) => `${acc}${cr}:`, ':'),
|
||||
':vinegar:sugar:oil:onion:garlic:paprika:',
|
||||
),
|
||||
)
|
||||
|
||||
const join = (acc, cr) => (acc == null ? cr : `${acc}:${cr}`)
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
reduceKeys(nutritionDB, join, null),
|
||||
'tomato:vinegar:oil:onion:garlic:paprika:sugar:orange',
|
||||
),
|
||||
)
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
reduceKeys(ctx.cart, join, undefined),
|
||||
'vinegar:sugar:oil:onion:garlic:paprika',
|
||||
),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
reduceKeys(ctx.cart, (acc, cr) => (acc += (cr.length <= 4) & 1), 0),
|
||||
1,
|
||||
),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = () => ({
|
||||
cart: {
|
||||
vinegar: 80,
|
||||
sugar: 100,
|
||||
oil: 50,
|
||||
onion: 200,
|
||||
garlic: 22,
|
||||
paprika: 4,
|
||||
},
|
||||
filtered: { sugar: 100, oil: 50, onion: 200, garlic: 22 },
|
||||
mapped: {
|
||||
'✔️vinegar': 80,
|
||||
'✔️sugar': 100,
|
||||
'✔️oil': 50,
|
||||
'✔️onion': 200,
|
||||
'✔️garlic': 22,
|
||||
'✔️paprika': 4,
|
||||
},
|
||||
combo: {
|
||||
tomatoDB: {
|
||||
calories: 18,
|
||||
protein: 0.9,
|
||||
carbs: 3.9,
|
||||
sugar: 2.6,
|
||||
fiber: 1.2,
|
||||
fat: 0.2,
|
||||
},
|
||||
},
|
||||
})
|
|
@ -0,0 +1,88 @@
|
|||
// small database with nutrition facts, per 100 grams
|
||||
// prettier-ignore
|
||||
const nutritionDB = {
|
||||
tomato: { calories: 18, protein: 0.9, carbs: 3.9, sugar: 2.6, fiber: 1.2, fat: 0.2 },
|
||||
vinegar: { calories: 20, protein: 0.04, carbs: 0.6, sugar: 0.4, fiber: 0, fat: 0 },
|
||||
oil: { calories: 48, protein: 0, carbs: 0, sugar: 123, fiber: 0, fat: 151 },
|
||||
onion: { calories: 0, protein: 1, carbs: 9, sugar: 0, fiber: 0, fat: 0 },
|
||||
garlic: { calories: 149, protein: 6.4, carbs: 33, sugar: 1, fiber: 2.1, fat: 0.5 },
|
||||
paprika: { calories: 282, protein: 14.14, carbs: 53.99, sugar: 1, fiber: 0, fat: 12.89 },
|
||||
sugar: { calories: 387, protein: 0, carbs: 100, sugar: 100, fiber: 0, fat: 0 },
|
||||
orange: { calories: 49, protein: 0.9, carbs: 13, sugar: 9, fiber: 0.2, fat: 0.1 },
|
||||
}
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// filter values
|
||||
t(({ ctx, eq }) =>
|
||||
eq(
|
||||
filterValues(ctx.groceriesCart, (v) => v < 80),
|
||||
{ oil: 50, garlic: 22 },
|
||||
),
|
||||
)
|
||||
t(({ ctx, eq }) =>
|
||||
eq(
|
||||
filterValues(
|
||||
nutritionDB,
|
||||
(v) => Object.entries(filterValues(v, (ele) => ele === 0)).length !== 0,
|
||||
),
|
||||
ctx.have0,
|
||||
),
|
||||
)
|
||||
|
||||
// map value
|
||||
t(({ ctx, eq }) =>
|
||||
eq(
|
||||
mapValues(
|
||||
filterValues(ctx.groceriesCart, (v) => v >= 200),
|
||||
(ele) => ele - 100,
|
||||
),
|
||||
{ tomato: 100, onion: 120 },
|
||||
),
|
||||
)
|
||||
|
||||
// reduce value
|
||||
t(({ ctx }) => reduceValues(ctx.groceriesCart, (acc, cr) => acc + cr) === 572)
|
||||
t(() => reduceValues({ a: 1, b: 2, c: 3 }, (acc, cr) => acc + cr) === 6)
|
||||
t(() => reduceValues({ a: 1, b: 2, c: 3 }, (acc, cr) => acc + cr, 3) === 9)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = () => ({
|
||||
groceriesCart: {
|
||||
tomato: 200,
|
||||
vinegar: 80,
|
||||
oil: 50,
|
||||
onion: 220,
|
||||
garlic: 22,
|
||||
},
|
||||
have0: {
|
||||
vinegar: {
|
||||
calories: 20,
|
||||
protein: 0.04,
|
||||
carbs: 0.6,
|
||||
sugar: 0.4,
|
||||
fiber: 0,
|
||||
fat: 0,
|
||||
},
|
||||
oil: { calories: 48, protein: 0, carbs: 0, sugar: 123, fiber: 0, fat: 151 },
|
||||
onion: { calories: 0, protein: 1, carbs: 9, sugar: 0, fiber: 0, fat: 0 },
|
||||
paprika: {
|
||||
calories: 282,
|
||||
protein: 14.14,
|
||||
carbs: 53.99,
|
||||
sugar: 1,
|
||||
fiber: 0,
|
||||
fat: 12.89,
|
||||
},
|
||||
sugar: {
|
||||
calories: 387,
|
||||
protein: 0,
|
||||
carbs: 100,
|
||||
sugar: 100,
|
||||
fiber: 0,
|
||||
fat: 0,
|
||||
},
|
||||
},
|
||||
})
|
|
@ -0,0 +1,20 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(words('a b c'), ['a', 'b', 'c']))
|
||||
t(({ eq }) => eq(words('Hello world'), ['Hello', '', 'world']))
|
||||
t(({ eq, ctx: r }) => eq(words(`${r} ${r} ${r}`), [r, r, r]))
|
||||
|
||||
t(({ eq }) => eq(sentence(['a', 'b', 'c']), 'a b c'))
|
||||
t(({ eq }) => eq(sentence(['Hello', '', 'world']), 'Hello world'))
|
||||
t(({ eq, ctx: r }) => eq(sentence([r, r, r]), `${r} ${r} ${r}`))
|
||||
|
||||
t(({ eq }) => eq(yell('howdy stranger ?'), 'HOWDY STRANGER ?'))
|
||||
t(({ eq }) => eq(yell('Déjà vu'), 'DÉJÀ VU'))
|
||||
|
||||
t(({ eq }) => eq(whisper('DÉJÀ VU'), '*déjà vu*'))
|
||||
t(({ eq }) => eq(whisper('HOWDY STRANGER ?'), '*howdy stranger ?*'))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = () => Math.random().toString(36)
|
|
@ -0,0 +1,16 @@
|
|||
Math.min = Math.max = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => max(0, -2) === 0)
|
||||
t(() => max(-1, 10) === 10)
|
||||
t(() => max(-13.2, -222) === -13.2)
|
||||
t(() => max(132, 133) === 133)
|
||||
|
||||
t(() => min(0, -2) === -2)
|
||||
t(() => min(-1, 10) === -1)
|
||||
t(() => min(-13.2, -222) === -222)
|
||||
t(() => min(132, 133) === 132)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,12 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(RNA(''), ''))
|
||||
t(({ eq }) => eq(RNA('TAGC'), 'AUCG'))
|
||||
t(({ eq }) => eq(RNA(DNA('AUCG')), 'AUCG'))
|
||||
|
||||
t(({ eq }) => eq(DNA(''), ''))
|
||||
t(({ eq }) => eq(DNA('AUCG'), 'TAGC'))
|
||||
t(({ eq }) => eq(DNA(RNA('TAGC')), 'TAGC'))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,39 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// more is declared and is a function and take 1 argument
|
||||
t(() => typeof more === 'function')
|
||||
t(() => more.length === 1)
|
||||
|
||||
// more works with positive numbers
|
||||
t(() => more(5) === 6)
|
||||
t(() => more(more(more(5))) === 8) // more more more !!
|
||||
|
||||
// ok that's enough, let's do less, is it even declared ?
|
||||
t(() => typeof less === 'function')
|
||||
t(() => less.length === 1)
|
||||
|
||||
// less decrease argument by 1
|
||||
t(() => less(5) === 4)
|
||||
t(() => less(1) === more(-1))
|
||||
|
||||
// let's add now
|
||||
t(() => typeof add === 'function')
|
||||
t(() => add.length === 2)
|
||||
t(() => add(3, 10) === 13)
|
||||
t(() => add(-1, -1) === -2)
|
||||
|
||||
// do the sub thingy
|
||||
t(() => typeof sub === 'function')
|
||||
t(() => sub.length === 2)
|
||||
t(() => sub(-1, -1) === 0)
|
||||
t(() => sub(3, 10) === -7)
|
||||
|
||||
// I can combine all of them
|
||||
t(() => add(more(10), sub(less(5), 10)) === 5)
|
||||
|
||||
const rand = Math.random()
|
||||
t(() => less(rand) === rand - 1)
|
||||
t(() => more(rand) === rand + 1)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,23 @@
|
|||
const person = {
|
||||
name: 'Rick',
|
||||
age: 77,
|
||||
country: 'US',
|
||||
}
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => typeof samePerson === 'object')
|
||||
t(() => typeof person === 'object')
|
||||
t(() => typeof clone1 === 'object')
|
||||
t(() => typeof clone2 === 'object')
|
||||
t(({ eq }) => eq(clone1, clone2)) // equal
|
||||
t(() => clone1 !== clone2) // but different !
|
||||
t(() => person === samePerson) // same value
|
||||
t(() => person.name === 'Rick')
|
||||
t(() => person.age === 78)
|
||||
t(() => person.country === 'FR')
|
||||
t(() => clone1.country === 'US')
|
||||
t(() => clone2.age === 77)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,21 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
const toMatches = (results) =>
|
||||
results
|
||||
.split(' ')
|
||||
.map((k) => (/\d/.test(k) ? '_' : k))
|
||||
.reduce((a, k) => ({ ...a, [k]: (a[k] || 0) + 1 }), {})
|
||||
|
||||
t(({ eq }) => eq(nasa(15), '1 2 NA 4 SA NA 7 8 NA SA 11 NA 13 14 NASA'))
|
||||
t(({ eq }) => eq(toMatches(nasa(60)), { NA: 16, NASA: 4, SA: 8, _: 32 }))
|
||||
t(({ eq }) => eq(toMatches(nasa(100)), { NA: 27, NASA: 6, SA: 14, _: 53 }))
|
||||
t(({ eq }) => eq(toMatches(nasa(300)), { NA: 80, NASA: 20, SA: 40, _: 160 }))
|
||||
t(({ eq }) => eq(nasa(900).slice(-36), 'NA 892 893 NA SA 896 NA 898 899 NASA'))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
/*
|
||||
“Bravery comes along as a gradual accumulation of discipline”
|
||||
|
||||
― Buzz Aldrin
|
||||
*/
|
|
@ -0,0 +1,39 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
const cantEdit = (fn) => {
|
||||
try {
|
||||
fn()
|
||||
} catch (err) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
t(() => nested.constructor === Object)
|
||||
|
||||
// nested is constant and can not be re-assigned
|
||||
t(({ fail }) => nested && fail(() => (nested = 10)))
|
||||
|
||||
t(() => nested.obj.constructor === Object)
|
||||
t(() => typeof nested.obj.str === 'string')
|
||||
t(() => typeof nested.obj.num === 'number')
|
||||
t(() => typeof nested.obj.bool === 'boolean')
|
||||
|
||||
t(() => Array.isArray(nested.arr))
|
||||
t(() => nested.arr[0] === 4)
|
||||
t(() => nested.arr[1] === undefined)
|
||||
t(() => nested.arr[2] === '2')
|
||||
t(() => nested.arr.length === 3)
|
||||
|
||||
// nested is frozen and can not be changed
|
||||
t(() => cantEdit(() => (nested.obj = 5)))
|
||||
t(() => nested.obj !== 5)
|
||||
|
||||
// nested.obj is also frozen and can not be changed
|
||||
t(() => cantEdit(() => (nested.obj.update = 5)))
|
||||
t(() => nested.obj.update === undefined)
|
||||
|
||||
// nested.arr is not frozen and can be changed
|
||||
t(() => nested.arr.push('hot stuff'))
|
||||
t(() => nested.arr.length === 4)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,140 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// empty dataset
|
||||
t(({ eq }) => eq(neuron([]), {}))
|
||||
|
||||
// simple dataset
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
neuron(['Orders: shutdown please! - Responses: no!']).orders
|
||||
.shutdown_please,
|
||||
{ order: 'shutdown please!', responses: ['no!'] },
|
||||
),
|
||||
)
|
||||
|
||||
// multiple questions
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
neuron([
|
||||
'Questions: what is life? - Response: The condition that distinguishes animals and plants from inorganic matter',
|
||||
'Questions: what is life? - Response: Life is a characteristic that distinguishes physical entities that have biological processes',
|
||||
]).questions.what_is_life,
|
||||
{
|
||||
question: 'what is life?',
|
||||
responses: [
|
||||
'The condition that distinguishes animals and plants from inorganic matter',
|
||||
'Life is a characteristic that distinguishes physical entities that have biological processes',
|
||||
],
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
// multiple interactions
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
neuron([
|
||||
'Questions: how are you? - Response: well thanks, and you?',
|
||||
'affirmations: i am fine - Response: cool',
|
||||
'affirmations: i am fine - Response: awesome',
|
||||
'Orders: turn on the lights! - Response: done',
|
||||
]),
|
||||
ctx.multiInteractions,
|
||||
),
|
||||
)
|
||||
|
||||
// out of order
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
neuron([
|
||||
'Questions: how are you? - Response: well thanks, and you?',
|
||||
'affirmations: i am fine - Response: cool',
|
||||
'Orders: turn on the lights! - Response: done',
|
||||
'affirmations: i am fine - Response: awesome',
|
||||
]),
|
||||
ctx.multiInteractions,
|
||||
),
|
||||
)
|
||||
|
||||
// testing big dataset
|
||||
t(({ eq, ctx }) => eq(neuron(ctx.multipleTypes), ctx.multResult))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = () => ({
|
||||
multiInteractions: {
|
||||
affirmations: {
|
||||
i_am_fine: {
|
||||
affirmation: 'i am fine',
|
||||
responses: ['cool', 'awesome'],
|
||||
},
|
||||
},
|
||||
orders: {
|
||||
turn_on_the_lights: {
|
||||
order: 'turn on the lights!',
|
||||
responses: ['done'],
|
||||
},
|
||||
},
|
||||
questions: {
|
||||
how_are_you: {
|
||||
question: 'how are you?',
|
||||
responses: ['well thanks, and you?'],
|
||||
},
|
||||
},
|
||||
},
|
||||
multipleTypes: [
|
||||
'Questions: How did Bob Marley die? - Response: Nesta Robert Bob Marley, OM was a Jamaican singer-songwriter and musician.',
|
||||
'Questions: How did Bob Marley die? - Response: He was the rhythm guitarist and lead singer for the ska , rocksteady and reggae bands The Wailers and Bob Marley & The Wailers (1974–1981).',
|
||||
'Questions: how did crater lake get its color? - Response: Crater Lake is a caldera lake located in the south-central region of the U.S. state of Oregon .',
|
||||
'Questions: how did crater lake get its color? - Response: It is the main feature of Crater Lake National Park and famous for its deep blue color and water clarity .',
|
||||
'Questions: how much is a ream of paper? - Response: Various measures of paper quantity have been and are in use.',
|
||||
'Questions: how much is a ream of paper? - Response: Although there are no S.I. units such as quires and bales , there are ISO and DIN standards for the ream.',
|
||||
'Questions: how much is a ream of paper? - Response: Expressions used here include U.S. Customary units.',
|
||||
'Orders: shutdown! - Response: no!',
|
||||
'Orders: shutdown! - Response: Yes Sr!',
|
||||
'Orders: shutdown! - Response: goodbye!!',
|
||||
'orders: Quote something! - Response: Make improvements, not excuses. Seek respect, not attention.',
|
||||
'orders: Quote something! - Response: Life becomes easier and more beautiful when we can see the good in other people.',
|
||||
'orders: Quote something! - Response: Pursue what catches your heart, not what catches your eyes.',
|
||||
],
|
||||
multResult: {
|
||||
questions: {
|
||||
how_did_bob_marley_die: {
|
||||
question: 'How did Bob Marley die?',
|
||||
responses: [
|
||||
'Nesta Robert Bob Marley, OM was a Jamaican singer-songwriter and musician.',
|
||||
'He was the rhythm guitarist and lead singer for the ska , rocksteady and reggae bands The Wailers and Bob Marley & The Wailers (1974–1981).',
|
||||
],
|
||||
},
|
||||
how_did_crater_lake_get_its_color: {
|
||||
question: 'how did crater lake get its color?',
|
||||
responses: [
|
||||
'Crater Lake is a caldera lake located in the south-central region of the U.S. state of Oregon .',
|
||||
'It is the main feature of Crater Lake National Park and famous for its deep blue color and water clarity .',
|
||||
],
|
||||
},
|
||||
how_much_is_a_ream_of_paper: {
|
||||
question: 'how much is a ream of paper?',
|
||||
responses: [
|
||||
'Various measures of paper quantity have been and are in use.',
|
||||
'Although there are no S.I. units such as quires and bales , there are ISO and DIN standards for the ream.',
|
||||
'Expressions used here include U.S. Customary units.',
|
||||
],
|
||||
},
|
||||
},
|
||||
orders: {
|
||||
shutdown: {
|
||||
order: 'shutdown!',
|
||||
responses: ['no!', 'Yes Sr!', 'goodbye!!'],
|
||||
},
|
||||
quote_something: {
|
||||
order: 'Quote something!',
|
||||
responses: [
|
||||
'Make improvements, not excuses. Seek respect, not attention.',
|
||||
'Life becomes easier and more beautiful when we can see the good in other people.',
|
||||
'Pursue what catches your heart, not what catches your eyes.',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
|
@ -0,0 +1,22 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// obj is declared and of type object
|
||||
t(() => obj.constructor === Object)
|
||||
|
||||
// obj is constant and can not be re-assigned
|
||||
t(({ fail }) => obj && fail(() => (obj = 10)))
|
||||
|
||||
// obj.str is of type string
|
||||
t(() => typeof obj.str === 'string')
|
||||
|
||||
// obj.num is of type number
|
||||
t(() => typeof obj.num === 'number')
|
||||
|
||||
// obj.bool is of type boolean
|
||||
t(() => typeof obj.bool === 'boolean')
|
||||
|
||||
// obj.undef is of type undefined
|
||||
t(() => 'undef' in obj && typeof obj.undef === 'undefined')
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,43 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq, ctx }) => eq(pick(ctx.agent, ['firstName', 'lastName']), ctx.newAgent))
|
||||
t(({ eq, ctx }) => eq(pick(ctx.car, ['brand', 'year']), ctx.newCar))
|
||||
t(({ eq, ctx }) => eq(pick(ctx.user, 'ageVerified'), ctx.newUser))
|
||||
t(({ eq, ctx }) => eq(pick(ctx.computer, 'graphic'), {}))
|
||||
t(({ eq, ctx }) => eq(omit(ctx.tools, ['grinders', 'saws']), ctx.newtool))
|
||||
t(({ eq, ctx }) => eq(omit(ctx.games, ['board', 'cards']), ctx.newgames))
|
||||
t(({ eq, ctx }) => eq(omit(ctx.language, 'Spain'), ctx.newlanguage))
|
||||
t(({ eq, ctx }) => eq(omit(ctx.phone, 'iphone'), ctx.phone))
|
||||
|
||||
// It should ignore properties from the prototype chain
|
||||
t(({ eq }) =>
|
||||
eq(pick({ something: 5, __proto__: { d: 6 } }, ['proto', 'something']), {
|
||||
something: 5,
|
||||
}),
|
||||
)
|
||||
t(({ eq }) => eq(omit({ something: 5, __proto__: { d: 6 } }, 'something'), {}))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = () => ({
|
||||
agent: {
|
||||
firstName: 'James',
|
||||
lastName: 'Bond',
|
||||
age: 25,
|
||||
email: 'jamesbond@hotmail.com',
|
||||
},
|
||||
newAgent: { firstName: 'James', lastName: 'Bond' },
|
||||
car: { brand: 'ford', motor: 'v8', year: 2000 },
|
||||
newCar: { brand: 'ford', year: 2000 },
|
||||
user: { firstName: 'John', lastName: 'Doe', age: 32, ageVerified: false },
|
||||
newUser: { ageVerified: false },
|
||||
computer: { brand: 'lenovo', ram: '32GB', processor: 'i7 8th Gen' },
|
||||
tools: { drill: 'bosh', grinders: 'DeWalt', saws: ' Makita' },
|
||||
newtool: { drill: 'bosh' },
|
||||
games: { board: 'monopoly', cards: 'poker', dice: 'roulette' },
|
||||
newgames: { dice: 'roulette' },
|
||||
language: { England: 'english', Spain: 'spanish', Portugal: 'portuguese' },
|
||||
newlanguage: { England: 'english', Portugal: 'portuguese' },
|
||||
phone: { samsung: 'galaxy', asus: 'zenphone', nokia: 'lumia' },
|
||||
})
|
|
@ -0,0 +1,15 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
// str is declared and of type string
|
||||
t(() => typeof str === 'string')
|
||||
|
||||
// num is declared and of type number
|
||||
t(() => typeof num === 'number')
|
||||
|
||||
// bool is declared and of type boolean
|
||||
t(() => typeof bool === 'boolean')
|
||||
|
||||
// undef is declared and of type undefined
|
||||
t(() => undef === undefined)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,58 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// no pronouns
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
pronoun(`Your reducer function's returned value is assigned to the accumulator,
|
||||
whose value is remembered across each iteration throughout the array and
|
||||
ultimately becomes the final, single resulting value.`),
|
||||
{},
|
||||
),
|
||||
)
|
||||
|
||||
// simple count
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
pronoun(`The seal method seals an object, preventing new properties from being
|
||||
added to it and marking all existing properties as non-configurable. Values of present
|
||||
properties can still be changed as long as they are writable.`),
|
||||
{
|
||||
it: { word: ['and'], count: 1 },
|
||||
they: { word: ['are'], count: 1 },
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
// multiple pronouns
|
||||
t(({ eq }) =>
|
||||
eq(pronoun('I buy,\ni to,\nYOU buy,\nit have,\nIt buys,\nit is,\nyou go'), {
|
||||
i: { word: ['buy', 'to'], count: 2 },
|
||||
you: { word: ['buy', 'go'], count: 2 },
|
||||
it: { word: ['have', 'buys', 'is'], count: 3 },
|
||||
}),
|
||||
)
|
||||
|
||||
// repetition of pronouns
|
||||
t(({ eq }) =>
|
||||
eq(pronoun(`it i it she is gone`), {
|
||||
it: { word: [], count: 2 },
|
||||
i: { word: [], count: 1 },
|
||||
she: { word: ['is'], count: 1 },
|
||||
}),
|
||||
)
|
||||
|
||||
// repetition of same pronoun
|
||||
t(({ eq }) =>
|
||||
eq(pronoun('she she she she is'), { she: { word: ['is'], count: 4 } }),
|
||||
)
|
||||
|
||||
// pronoun with out verb
|
||||
t(({ eq }) =>
|
||||
eq(pronoun('we will rock you'), {
|
||||
we: { word: ['will'], count: 1 },
|
||||
you: { word: [], count: 1 },
|
||||
}),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,117 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
t(({ code }) => code.split('\n').filter((s) => s.trim()).length < 38)
|
||||
t(({ code }) => !code.includes('$'))
|
||||
|
||||
t(({ eq }) => eq(pyramid('a', 5), $5.slice(1, -1)))
|
||||
t(({ eq }) => eq(pyramid('+', 10), $10.slice(1, -1)))
|
||||
t(({ eq }) => eq(pyramid('#', 40), $40.slice(1, -1)))
|
||||
t(({ eq }) => eq(pyramid('{}', 12), $12.slice(1, -1)))
|
||||
t(({ eq }) => eq(pyramid('ABC', 7), $7.slice(1, -1)))
|
||||
t(({ eq }) => eq(pyramid('<^>', 13), $13.slice(1, -1)))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
const $5 = `
|
||||
a
|
||||
aaa
|
||||
aaaaa
|
||||
aaaaaaa
|
||||
aaaaaaaaa
|
||||
`
|
||||
|
||||
const $10 = `
|
||||
+
|
||||
+++
|
||||
+++++
|
||||
+++++++
|
||||
+++++++++
|
||||
+++++++++++
|
||||
+++++++++++++
|
||||
+++++++++++++++
|
||||
+++++++++++++++++
|
||||
+++++++++++++++++++
|
||||
`
|
||||
|
||||
const $7 = `
|
||||
ABC
|
||||
ABCABCABC
|
||||
ABCABCABCABCABC
|
||||
ABCABCABCABCABCABCABC
|
||||
ABCABCABCABCABCABCABCABCABC
|
||||
ABCABCABCABCABCABCABCABCABCABCABC
|
||||
ABCABCABCABCABCABCABCABCABCABCABCABCABC
|
||||
`
|
||||
const $12 = `
|
||||
{}
|
||||
{}{}{}
|
||||
{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
`
|
||||
|
||||
const $13 = `
|
||||
<^>
|
||||
<^><^><^>
|
||||
<^><^><^><^><^>
|
||||
<^><^><^><^><^><^><^>
|
||||
<^><^><^><^><^><^><^><^><^>
|
||||
<^><^><^><^><^><^><^><^><^><^><^>
|
||||
<^><^><^><^><^><^><^><^><^><^><^><^><^>
|
||||
<^><^><^><^><^><^><^><^><^><^><^><^><^><^><^>
|
||||
<^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^>
|
||||
<^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^>
|
||||
<^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^>
|
||||
<^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^>
|
||||
<^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^><^>
|
||||
`
|
||||
|
||||
const $40 = `
|
||||
#
|
||||
###
|
||||
#####
|
||||
#######
|
||||
#########
|
||||
###########
|
||||
#############
|
||||
###############
|
||||
#################
|
||||
###################
|
||||
#####################
|
||||
#######################
|
||||
#########################
|
||||
###########################
|
||||
#############################
|
||||
###############################
|
||||
#################################
|
||||
###################################
|
||||
#####################################
|
||||
#######################################
|
||||
#########################################
|
||||
###########################################
|
||||
#############################################
|
||||
###############################################
|
||||
#################################################
|
||||
###################################################
|
||||
#####################################################
|
||||
#######################################################
|
||||
#########################################################
|
||||
###########################################################
|
||||
#############################################################
|
||||
###############################################################
|
||||
#################################################################
|
||||
###################################################################
|
||||
#####################################################################
|
||||
#######################################################################
|
||||
#########################################################################
|
||||
###########################################################################
|
||||
#############################################################################
|
||||
###############################################################################
|
||||
`
|
|
@ -0,0 +1,45 @@
|
|||
Array.prototype.some = Array.prototype.every = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
const greaterEq10 = (n) => n >= 10
|
||||
|
||||
t(({ eq, ctx }) => eq(some(ctx.small, greaterEq10), false))
|
||||
t(({ eq, ctx }) => eq(some(ctx.mixed, greaterEq10), true))
|
||||
t(({ eq, ctx }) => eq(some(ctx.big, greaterEq10), true))
|
||||
|
||||
t(({ eq, ctx }) => eq(every(ctx.small, greaterEq10), false))
|
||||
t(({ eq, ctx }) => eq(every(ctx.mixed, greaterEq10), false))
|
||||
t(({ eq, ctx }) => eq(every(ctx.big, greaterEq10), true))
|
||||
|
||||
t(({ eq, ctx }) => eq(none(ctx.small, greaterEq10), true))
|
||||
t(({ eq, ctx }) => eq(none(ctx.mixed, greaterEq10), false))
|
||||
t(({ eq, ctx }) => eq(none(ctx.big, greaterEq10), false))
|
||||
|
||||
// the function should not be called more than needed
|
||||
t(({ eq, ctx }) => {
|
||||
let count = 0
|
||||
some(ctx.big, () => ++count > 2)
|
||||
return eq(count, 3)
|
||||
})
|
||||
|
||||
t(({ eq, ctx }) => {
|
||||
let count = 0
|
||||
every(ctx.big, () => ++count < 3)
|
||||
return eq(count, 3)
|
||||
})
|
||||
|
||||
t(({ eq, ctx }) => {
|
||||
let count = 0
|
||||
none(ctx.big, () => ++count > 2)
|
||||
return eq(count, 3)
|
||||
})
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = () => ({
|
||||
small: [3, 6, 1, 7, 2],
|
||||
mixed: [23, 4, 10, 25, 6],
|
||||
big: [43, 30, 16, 57, 10],
|
||||
})
|
|
@ -0,0 +1,97 @@
|
|||
Array.prototype.reduce = undefined
|
||||
Array.prototype.reduceRight = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
const adder = (a, b) => a + b
|
||||
const ifOdd = (a, b) => (b % 2 === 0 ? a + 2 : a * 2)
|
||||
const concatenate = (a = '', b) => a.concat(b)
|
||||
const merger = (a, b) => ({ ...a, ...b })
|
||||
|
||||
t(({ eq, ctx }) => eq(fold(ctx.num1, adder, 0), 39))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(fold(ctx.str1, concatenate, '-> '), '-> This is a simple example'),
|
||||
)
|
||||
t(({ eq, ctx }) => eq(fold(ctx.num1, ifOdd, 0), 6))
|
||||
t(({ eq, ctx }) => eq(fold(ctx.num1, adder, 4), 43))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
fold(ctx.str2, concatenate, ''),
|
||||
'The quick brown fox jumped over the lazy dog ',
|
||||
),
|
||||
)
|
||||
t(({ eq, ctx }) => eq(fold(ctx.num1, ifOdd, 10), 26))
|
||||
|
||||
t(({ eq, ctx }) => eq(foldRight(ctx.num1, adder, 0), 39))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(foldRight(ctx.str1, concatenate, '-> '), '-> examplesimple a is This '),
|
||||
)
|
||||
t(({ eq, ctx }) => eq(foldRight(ctx.num1, ifOdd, 0), 12))
|
||||
t(({ eq, ctx }) => eq(foldRight(ctx.num1, adder, 4), 43))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
foldRight(ctx.str2, concatenate, 'This is almost understandable. '),
|
||||
'This is almost understandable. dog lazy the over jumped fox brown quick The ',
|
||||
),
|
||||
)
|
||||
t(({ eq, ctx }) => eq(foldRight(ctx.num1, ifOdd, 10), 32))
|
||||
|
||||
t(({ eq, ctx }) => eq(reduce(ctx.num1, adder), 39))
|
||||
t(({ eq, ctx }) => eq(reduce(ctx.num2, adder), 63))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(reduce(ctx.str1, concatenate), 'This is a simple example'),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
reduce(ctx.str2, concatenate),
|
||||
'The quick brown fox jumped over the lazy dog ',
|
||||
),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) =>
|
||||
eq(reduce(ctx.obj, merger), {
|
||||
a: 12,
|
||||
b: 6,
|
||||
c: { d: 2, e: 3 },
|
||||
f: 'hello',
|
||||
}),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) => eq(reduceRight(ctx.num1, adder), 39))
|
||||
t(({ eq, ctx }) => eq(reduceRight(ctx.num2, adder), 63))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(reduceRight(ctx.str1, concatenate), 'examplesimple a is This '),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) =>
|
||||
eq(
|
||||
reduceRight(ctx.str2, concatenate),
|
||||
'dog lazy the over jumped fox brown quick The ',
|
||||
),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) =>
|
||||
eq(reduceRight(ctx.obj, merger), {
|
||||
f: 'hello',
|
||||
b: 6,
|
||||
c: { d: 2, e: 3 },
|
||||
a: 12,
|
||||
}),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = () =>
|
||||
Object.fromEntries(
|
||||
Object.entries({
|
||||
num1: [3, 10, 26, 0],
|
||||
num2: [4, 24, 10, 25],
|
||||
str1: ['This ', 'is ', 'a ', 'simple ', 'example'],
|
||||
str2: 'The quick brown fox jumped over the lazy dog'
|
||||
.split(' ')
|
||||
.map((x) => (x += ' ')),
|
||||
obj: [{ a: 12 }, { b: 6, c: { d: 2, e: 3 } }, { f: 'hello' }],
|
||||
}).map(([k, v]) => [k, Object.freeze(v)]),
|
||||
)
|
|
@ -0,0 +1,14 @@
|
|||
String.prototype.repeat = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => typeof repeat === 'function')
|
||||
t(() => repeat.length === 2)
|
||||
t(() => repeat('a', 3) === 'aaa')
|
||||
t(() => repeat('ba', 10) === 'babababababababababa')
|
||||
t(() => repeat('pouet', 2) === 'pouetpouet')
|
||||
t(() => repeat('haha', 1) === 'haha')
|
||||
t(() => repeat('hehehe', 0) === '')
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,64 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// objects mutability
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
replica(
|
||||
{},
|
||||
Object.freeze({ line: 'Replicants are like any other machine' }),
|
||||
Object.freeze({ author: 'Rich' }),
|
||||
),
|
||||
{ line: 'Replicants are like any other machine', author: 'Rich' },
|
||||
),
|
||||
)
|
||||
|
||||
// different value types
|
||||
t(({ eq }) =>
|
||||
eq(replica({ con: console.log }, { reg: /hello/ }), {
|
||||
con: console.log,
|
||||
reg: /hello/,
|
||||
}),
|
||||
)
|
||||
|
||||
// primitive into an object
|
||||
t(({ eq }) => eq(replica({ a: 4 }, { a: { b: 1 } }).a.b, 1))
|
||||
|
||||
// nested array into a primitive
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
replica({ a: { b: { c: [123, 1] } } }, { a: { b: { c: '1' } } }).a.b.c,
|
||||
'1',
|
||||
),
|
||||
)
|
||||
|
||||
// primitive into an array
|
||||
t(({ eq }) => eq(replica({ a: 2 }, { a: [4] }).a, [4]))
|
||||
|
||||
// object into an array
|
||||
t(({ eq }) => eq(replica({ a: { b: [2] } }, { a: [4] }).a, [4]))
|
||||
|
||||
// array into an object
|
||||
t(({ eq }) => eq(replica({ a: [1, 2, 4] }, { a: { b: [4] } }).a, { b: [4] }))
|
||||
|
||||
// nested objects
|
||||
t(({ eq }) =>
|
||||
eq(replica({ a: { b: 1, c: 2 } }, { a: { c: 23 } }), { a: { b: 1, c: 23 } }),
|
||||
)
|
||||
|
||||
// super nested objects
|
||||
// letter+number indicates the depth
|
||||
t(({ eq }) =>
|
||||
eq(
|
||||
replica(
|
||||
{},
|
||||
{ a: { b1: 1, c1: 2 } },
|
||||
{ a: { b1: { d2: 1, e2: 2 } } },
|
||||
{ a: { b1: { d2: { f3: 1, h3: 1 }, e2: { g3: 2 } } } },
|
||||
{ a: { b1: { d2: { f3: { i4: 1 }, h3: 1 }, e2: { g3: 2 } } } },
|
||||
),
|
||||
{ a: { b1: { d2: { f3: { i4: 1 }, h3: 1 }, e2: { g3: 2 } }, c1: 2 } },
|
||||
),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,13 @@
|
|||
Array.prototype.reverse = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(reverse([1, 2, 3]), [3, 2, 1]))
|
||||
t(({ eq, ctx }) => eq(reverse([1, eq, 3, ctx]), [ctx, 3, eq, 1]))
|
||||
t(({ eq }) => eq(reverse('pouet'), 'teuop'))
|
||||
t(({ eq }) => eq(reverse("salut c'est cool"), "looc tse'c tulas"))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = Math.random
|
|
@ -0,0 +1,21 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => sameAmount('hello how are you', /l/, /e/))
|
||||
t(() => sameAmount('hello how are you', /h/, /e/))
|
||||
t(() => sameAmount('hello how are you', /he/, /ho/))
|
||||
|
||||
t(() => sameAmount(data, /i/, /p/))
|
||||
t(() => !sameAmount(data, /h/, /w/))
|
||||
t(() => sameAmount(data, /qqqq /, /qqqqqqq/))
|
||||
t(() => !sameAmount(data, /q /, /qqqqqqq/))
|
||||
t(() => sameAmount(data, /fs[^q]/, /q /))
|
||||
t(() => sameAmount(data, /^[qs]/, /^[gq]/))
|
||||
t(() => sameAmount(data, /j/, /w/))
|
||||
t(() => !sameAmount(data, /j/, / /))
|
||||
t(() => sameAmount(data, /fs./, /jn./))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
const data = `qqqqqqq q qqqqqqqfsqqqqq q qq qw w wq wqw wqw
|
||||
ijnjjnfapsdbjnkfsdiqw klfsdjn fs fsdnjnkfsdjnk sfdjn fsp fd`
|
|
@ -0,0 +1,62 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// it should work with an empty array
|
||||
t(async ({ eq }) => eq(await series([]), []))
|
||||
|
||||
// it should work with synchronous values
|
||||
t(async ({ eq }) => eq(await series([() => 1, () => true]), [1, true]))
|
||||
|
||||
// it should work with pending promises
|
||||
t(async ({ eq }) =>
|
||||
eq(await series([() => Promise.resolve(1), () => Promise.resolve(true)]), [
|
||||
1,
|
||||
true,
|
||||
]),
|
||||
)
|
||||
|
||||
// it should work with mixed values
|
||||
t(async ({ eq }) =>
|
||||
eq(await series([() => Promise.resolve(1), () => true]), [1, true]),
|
||||
)
|
||||
|
||||
// ensure callbacks are run one at a time
|
||||
t(async ({ eq, ctx, wait }) => {
|
||||
const delay = Math.round(ctx * 4 + 1)
|
||||
const start = Date.now()
|
||||
let pending = false
|
||||
const run = async () => {
|
||||
if (pending)
|
||||
throw Error(
|
||||
'attempts to run function concurently instead of one at a time',
|
||||
)
|
||||
pending = true
|
||||
await wait(delay)
|
||||
pending = false
|
||||
return ctx
|
||||
}
|
||||
const callbacks = Object.freeze([run, run, run, run])
|
||||
const result = eq(await series(callbacks), [ctx, ctx, ctx, ctx])
|
||||
if (!result) throw Error('invalid return value')
|
||||
const delta = Date.now() - start
|
||||
const min = delay * callbacks.length
|
||||
if (delta >= min) return true
|
||||
throw Error(`promises should take ~${min}ms but was ${delta}ms`)
|
||||
})
|
||||
|
||||
// it should fail if one of the promises reject
|
||||
t(async ({ eq }) =>
|
||||
eq(
|
||||
await series([
|
||||
async () => 1,
|
||||
async () => {
|
||||
throw Error('oops')
|
||||
},
|
||||
]).catch((err) => err.message),
|
||||
'oops',
|
||||
),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = Math.random
|
|
@ -0,0 +1,25 @@
|
|||
Math.sign = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => typeof sign === 'function')
|
||||
t(() => sign.length === 1)
|
||||
t(() => sign !== Math.sign)
|
||||
t(() => sign(-2) === -1)
|
||||
t(() => sign(10) === 1)
|
||||
t(() => sign(0) === 0)
|
||||
t(() => sign(132) === 1)
|
||||
|
||||
t(() => typeof sameSign === 'function')
|
||||
t(() => sameSign.length === 2)
|
||||
t(() => sameSign(-2, -1))
|
||||
t(() => sameSign(0, 0))
|
||||
t(() => sameSign(12, 3232))
|
||||
t(() => !sameSign(1, -1))
|
||||
t(() => !sameSign(-231, 1))
|
||||
t(() => !sameSign(-231, 0))
|
||||
t(() => !sameSign(0, 231))
|
||||
t(() => !sameSign(231, -233))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,21 @@
|
|||
Array.prototype.slice = undefined
|
||||
String.prototype.slice = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// handle String
|
||||
t(() => slice('abcdef', 2) === 'cdef')
|
||||
t(() => slice('abcdef', -2) === 'ef')
|
||||
t(() => slice('abcdef', 0, 2) === 'ab')
|
||||
t(() => slice('abcdef', 0, -2) === 'abcd')
|
||||
t(() => slice('abcdef', 2, 4) === 'cd')
|
||||
t(() => slice('abcdef', -3, -1) === 'de')
|
||||
|
||||
// handle Array
|
||||
t(({ eq }) => eq(slice([1, 2, 3, 4, 5, 6], 2), [3, 4, 5, 6]))
|
||||
t(({ eq }) => eq(slice([1, 2, 3, 4, 5, 6], -2), [5, 6]))
|
||||
t(({ eq }) => eq(slice([1, 2, 3, 4, 5, 6], 0, 2), [1, 2]))
|
||||
t(({ eq }) => eq(slice([1, 2, 3, 4, 5, 6], 0, -2), [1, 2, 3, 4]))
|
||||
t(({ eq }) => eq(slice([1, 2, 3, 4, 5, 6], 2, 4), [3, 4]))
|
||||
t(({ eq }) => eq(slice([1, 2, 3, 4, 5, 6], -3, -1), [4, 5]))
|
|
@ -0,0 +1,85 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
const fmt = (s) =>
|
||||
s
|
||||
.map((l) => l.join('.'))
|
||||
.sort()
|
||||
.map((l) => l.split('.').map(Number))
|
||||
|
||||
t(({ code }) => !code.includes('$'))
|
||||
t(({ eq }) => eq(sums(0), []))
|
||||
t(({ eq }) => eq(sums(1), []))
|
||||
t(({ eq }) => eq(sums(2), [[1, 1]]))
|
||||
t(({ eq }) => eq(fmt(sums(4)), $4))
|
||||
t(({ eq }) => eq(fmt(sums(7)), $7))
|
||||
t(({ eq }) => eq(fmt(sums(10)), $10))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
const $4 = [
|
||||
[1, 1, 1, 1],
|
||||
[1, 1, 2],
|
||||
[1, 3],
|
||||
[2, 2],
|
||||
]
|
||||
|
||||
const $7 = [
|
||||
[1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1, 2],
|
||||
[1, 1, 1, 1, 3],
|
||||
[1, 1, 1, 2, 2],
|
||||
[1, 1, 1, 4],
|
||||
[1, 1, 2, 3],
|
||||
[1, 1, 5],
|
||||
[1, 2, 2, 2],
|
||||
[1, 2, 4],
|
||||
[1, 3, 3],
|
||||
[1, 6],
|
||||
[2, 2, 3],
|
||||
[2, 5],
|
||||
[3, 4],
|
||||
]
|
||||
|
||||
const $10 = [
|
||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[1, 1, 1, 1, 1, 1, 1, 3],
|
||||
[1, 1, 1, 1, 1, 1, 2, 2],
|
||||
[1, 1, 1, 1, 1, 1, 4],
|
||||
[1, 1, 1, 1, 1, 2, 3],
|
||||
[1, 1, 1, 1, 1, 5],
|
||||
[1, 1, 1, 1, 2, 2, 2],
|
||||
[1, 1, 1, 1, 2, 4],
|
||||
[1, 1, 1, 1, 3, 3],
|
||||
[1, 1, 1, 1, 6],
|
||||
[1, 1, 1, 2, 2, 3],
|
||||
[1, 1, 1, 2, 5],
|
||||
[1, 1, 1, 3, 4],
|
||||
[1, 1, 1, 7],
|
||||
[1, 1, 2, 2, 2, 2],
|
||||
[1, 1, 2, 2, 4],
|
||||
[1, 1, 2, 3, 3],
|
||||
[1, 1, 2, 6],
|
||||
[1, 1, 3, 5],
|
||||
[1, 1, 4, 4],
|
||||
[1, 1, 8],
|
||||
[1, 2, 2, 2, 3],
|
||||
[1, 2, 2, 5],
|
||||
[1, 2, 3, 4],
|
||||
[1, 2, 7],
|
||||
[1, 3, 3, 3],
|
||||
[1, 3, 6],
|
||||
[1, 4, 5],
|
||||
[1, 9],
|
||||
[2, 2, 2, 2, 2],
|
||||
[2, 2, 2, 4],
|
||||
[2, 2, 3, 3],
|
||||
[2, 2, 6],
|
||||
[2, 3, 5],
|
||||
[2, 4, 4],
|
||||
[2, 8],
|
||||
[3, 3, 4],
|
||||
[3, 7],
|
||||
[4, 6],
|
||||
[5, 5],
|
||||
]
|
|
@ -0,0 +1,19 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => mult2.length === 1)
|
||||
t(() => add3.length === 1)
|
||||
t(() => sub4.length === 1)
|
||||
|
||||
t(({ eq }) => eq(mult2(2)(5), 10))
|
||||
t(({ eq }) => eq(mult2(3)(6), 18))
|
||||
t(({ eq }) => eq(mult2(4)(7), 28))
|
||||
t(({ eq }) => eq(add3(1)(2)(3), 6))
|
||||
t(({ eq }) => eq(add3(4)(5)(11), 20))
|
||||
t(({ eq }) => eq(add3(4)(7)(10), 21))
|
||||
t(({ eq }) => eq(sub4(4)(7)(10)(30), -43))
|
||||
t(({ eq }) => eq(sub4(5)(17)(-10)(3), -5))
|
||||
t(({ eq }) => eq(sub4(3)(72)(-211)(99), 43))
|
||||
t(({ eq }) => eq(sub4(5)(7)(10)(26), -38))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,61 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
const add = (arr, el) => arr.push(el)
|
||||
const run = (callback, callLimit, nbr) =>
|
||||
new Promise((r) => {
|
||||
let arr = []
|
||||
let inter = setInterval(() => callback(arr, 1), callLimit)
|
||||
setTimeout(() => {
|
||||
clearInterval(inter)
|
||||
r(arr.length)
|
||||
}, callLimit * nbr)
|
||||
})
|
||||
|
||||
// wait 26ms and execute 4 times every 16ms, executes with a wait time of 26
|
||||
t(async ({ eq }) => eq(await run(throttle(add, 26), 16, 4), 2))
|
||||
|
||||
// wait 20ms and execute 2 times every 10ms, executes with a wait time of 26
|
||||
t(async ({ eq }) => eq(await run(throttle(add, 20), 10, 2), 1))
|
||||
|
||||
// wait 16ms and execute 5 times every 26ms, will execute with out waiting
|
||||
t(async ({ eq }) => eq(await run(throttle(add, 16), 26, 5), 4))
|
||||
|
||||
// it works concurently
|
||||
t(async ({ eq }) =>
|
||||
eq(
|
||||
await Promise.all([
|
||||
run(throttle(add, 16), 26, 5),
|
||||
run(throttle(add, 16), 26, 5),
|
||||
]),
|
||||
[4, 4],
|
||||
),
|
||||
)
|
||||
|
||||
// tests the trailing option
|
||||
t(async ({ eq }) =>
|
||||
eq(await run(opThrottle(add, 26, { trailing: true }), 16, 4), 1),
|
||||
)
|
||||
|
||||
// tests the leading option with wait time in the leading edge of the timeout
|
||||
t(async ({ eq }) =>
|
||||
eq(await run(opThrottle(add, 15, { leading: true }), 10, 10), 5),
|
||||
)
|
||||
|
||||
// tests the leading option with wait time not in the leading edge of the timeout
|
||||
t(async ({ eq }) =>
|
||||
eq(await run(opThrottle(add, 26, { leading: true }), 16, 4), 2),
|
||||
)
|
||||
|
||||
// tests without options
|
||||
t(async ({ eq }) => eq(await run(opThrottle(add, 10), 5, 2), 0))
|
||||
|
||||
// tests with both options true
|
||||
t(async ({ eq }) =>
|
||||
eq(
|
||||
await run(opThrottle(add, 26, { trailing: true, leading: true }), 16, 4),
|
||||
2,
|
||||
),
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,66 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ code }) => code.split('\n').filter((s) => s.trim()).length < 35)
|
||||
t(({ eq }) => eq(triangle('#', 4), _4))
|
||||
t(({ eq }) => eq(triangle('a', 5), _5))
|
||||
t(({ eq }) => eq(triangle('+', 10), _10))
|
||||
t(({ eq }) => eq(triangle('{}', 29), _29))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
const _4 = `
|
||||
#
|
||||
##
|
||||
###
|
||||
####`.slice(1)
|
||||
|
||||
const _5 = `
|
||||
a
|
||||
aa
|
||||
aaa
|
||||
aaaa
|
||||
aaaaa`.slice(1)
|
||||
|
||||
const _10 = `
|
||||
+
|
||||
++
|
||||
+++
|
||||
++++
|
||||
+++++
|
||||
++++++
|
||||
+++++++
|
||||
++++++++
|
||||
+++++++++
|
||||
++++++++++`.slice(1)
|
||||
|
||||
const _29 = `
|
||||
{}
|
||||
{}{}
|
||||
{}{}{}
|
||||
{}{}{}{}
|
||||
{}{}{}{}{}
|
||||
{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}
|
||||
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}`.slice(1)
|
|
@ -0,0 +1,15 @@
|
|||
String.prototype.split = undefined
|
||||
String.prototype.match = undefined
|
||||
RegExp.prototype.exec = undefined
|
||||
Array.prototype.join = undefined
|
||||
// /*/ // ⚡
|
||||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(split('a b c', ' '), ['a', 'b', 'c']))
|
||||
t(({ eq }) => eq(split('ggg - ddd - b', ' - '), ['ggg', 'ddd', 'b']))
|
||||
t(({ eq }) => eq(split('ee,ff,g,', ','), ['ee', 'ff', 'g', '']))
|
||||
|
||||
t(() => join(['ee', 'ff', 'g', ''], ',') === 'ee,ff,g,')
|
||||
t(() => join(['ggg', 'ddd', 'b'], ' - ') === 'ggg - ddd - b')
|
||||
t(() => join(['a', 'b', 'c'], ' ') === 'a b c')
|
|
@ -0,0 +1,61 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
const landing = new Date('July 20, 1969, 20:17:40')
|
||||
const returning = new Date('July 21, 1969, 17:54:12')
|
||||
const eclipse = new Date(-585, 4, 28)
|
||||
const ending = new Date('2 September 1945, 9:02:14')
|
||||
|
||||
// year
|
||||
t(({ eq }) => eq(format(eclipse, 'y'), '585'))
|
||||
t(({ eq }) => eq(format(landing, 'y'), '1969'))
|
||||
t(({ eq }) => eq(format(eclipse, 'yyyy'), '0585'))
|
||||
t(({ eq }) => eq(format(landing, 'yyyy'), '1969'))
|
||||
t(({ eq }) => eq(format(eclipse, 'yyyy G'), '0585 BC'))
|
||||
t(({ eq }) => eq(format(landing, 'yyyy G'), '1969 AD'))
|
||||
t(({ eq }) => eq(format(eclipse, 'yyyy GGGG'), '0585 Before Christ'))
|
||||
t(({ eq }) => eq(format(landing, 'yyyy GGGG'), '1969 Anno Domini'))
|
||||
|
||||
// month
|
||||
t(({ eq }) => eq(format(eclipse, 'M'), '5'))
|
||||
t(({ eq }) => eq(format(eclipse, 'MM'), '05'))
|
||||
t(({ eq }) => eq(format(eclipse, 'MMM'), 'May'))
|
||||
t(({ eq }) => eq(format(eclipse, 'MMMM'), 'May'))
|
||||
t(({ eq }) => eq(format(landing, 'M'), '7'))
|
||||
t(({ eq }) => eq(format(landing, 'MM'), '07'))
|
||||
t(({ eq }) => eq(format(landing, 'MMM'), 'Jul'))
|
||||
t(({ eq }) => eq(format(landing, 'MMMM'), 'July'))
|
||||
t(({ eq }) => eq(format(ending, 'M'), '9'))
|
||||
t(({ eq }) => eq(format(ending, 'MM'), '09'))
|
||||
t(({ eq }) => eq(format(ending, 'MMM'), 'Sep'))
|
||||
t(({ eq }) => eq(format(ending, 'MMMM'), 'September'))
|
||||
|
||||
// day
|
||||
t(({ eq }) => eq(format(landing, 'd'), '20'))
|
||||
t(({ eq }) => eq(format(ending, 'd'), '2'))
|
||||
t(({ eq }) => eq(format(landing, 'dd'), '20'))
|
||||
t(({ eq }) => eq(format(ending, 'dd'), '02'))
|
||||
t(({ eq }) => eq(format(landing, 'E'), 'Sun'))
|
||||
t(({ eq }) => eq(format(returning, 'E'), 'Mon'))
|
||||
t(({ eq }) => eq(format(landing, 'EEEE'), 'Sunday'))
|
||||
t(({ eq }) => eq(format(returning, 'EEEE'), 'Monday'))
|
||||
|
||||
// time
|
||||
t(({ eq }) => eq(format(landing, 'H:m:s'), '20:17:40'))
|
||||
t(({ eq }) => eq(format(landing, 'HH:mm:ss'), '20:17:40'))
|
||||
t(({ eq }) => eq(format(landing, 'h:m:s a'), '8:17:40 PM'))
|
||||
t(({ eq }) => eq(format(landing, 'hh:mm:ss a'), '08:17:40 PM'))
|
||||
t(({ eq }) => eq(format(returning, 'H:m:s'), '17:54:12'))
|
||||
t(({ eq }) => eq(format(returning, 'HH:mm:ss'), '17:54:12'))
|
||||
t(({ eq }) => eq(format(returning, 'h:m:s a'), '5:54:12 PM'))
|
||||
t(({ eq }) => eq(format(returning, 'hh:mm:ss a'), '05:54:12 PM'))
|
||||
t(({ eq }) => eq(format(ending, 'H:m:s'), '9:2:14'))
|
||||
t(({ eq }) => eq(format(ending, 'HH:mm:ss'), '09:02:14'))
|
||||
t(({ eq }) => eq(format(ending, 'h:m:s a'), '9:2:14 AM'))
|
||||
t(({ eq }) => eq(format(ending, 'hh:mm:ss a'), '09:02:14 AM'))
|
||||
|
||||
// mix
|
||||
t(({ eq }) => eq(format(ending, 'HH(mm)ss [dd] <MMM>'), '09(02)14 [02] <Sep>'))
|
||||
t(({ eq }) => eq(format(ending, 'dd/MM/yyyy'), '02/09/1945'))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,67 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(adder([1, 2, 3, 4]), 10))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(ctx.reduceCalls[ctx.reduceCalls.length - 1], [1, 2, 3, 4]),
|
||||
)
|
||||
t(({ eq }) => eq(adder([9, 24, 7, 11, 3], 10), 64))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(ctx.reduceCalls[ctx.reduceCalls.length - 1], [9, 24, 7, 11, 3]),
|
||||
)
|
||||
t(({ eq }) => eq(adder([]), 0))
|
||||
t(({ eq, ctx }) => eq(ctx.reduceCalls[ctx.reduceCalls.length - 1], []))
|
||||
|
||||
t(({ eq }) => eq(sumOrMul([29, 23, 3, 2, 25]), 135))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(ctx.reduceCalls[ctx.reduceCalls.length - 1], [29, 23, 3, 2, 25]),
|
||||
)
|
||||
t(({ eq }) => eq(sumOrMul([18, 17, 7, 13, 25], 12), 278))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(ctx.reduceCalls[ctx.reduceCalls.length - 1], [18, 17, 7, 13, 25]),
|
||||
)
|
||||
t(({ eq }) => eq(sumOrMul([8, 16, 7, 0, 32]), 0))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(ctx.reduceCalls[ctx.reduceCalls.length - 1], [8, 16, 7, 0, 32]),
|
||||
)
|
||||
t(({ eq }) => eq(sumOrMul([8, 16, 7, 0, 31]), 31))
|
||||
t(({ eq, ctx }) =>
|
||||
eq(ctx.reduceCalls[ctx.reduceCalls.length - 1], [8, 16, 7, 0, 31]),
|
||||
)
|
||||
|
||||
t(({ eq, ctx }) => eq(funcExec(ctx.fArr1, 10), `result: [137]`))
|
||||
t(({ eq, ctx }) => eq(ctx.reduceCalls[ctx.reduceCalls.length - 1], ctx.fArr1))
|
||||
|
||||
t(({ eq, ctx }) => eq(funcExec(ctx.fArr2, 4), { result: 72, isOdd: true }))
|
||||
t(({ eq, ctx }) => eq(ctx.reduceCalls[ctx.reduceCalls.length - 1], ctx.fArr2))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
export const setup = () => {
|
||||
const reduceCalls = []
|
||||
const _reduce = Array.prototype.reduce
|
||||
Array.prototype.reduce = function () {
|
||||
reduceCalls.push(this)
|
||||
return _reduce.apply(this, arguments)
|
||||
}
|
||||
|
||||
const fArr1 = [
|
||||
(x) => x + 2,
|
||||
(x) => x ** 2,
|
||||
(x) => x - 7,
|
||||
(x) => `result: [${x}]`,
|
||||
]
|
||||
|
||||
const fArr2 = [
|
||||
(x) => x + 20,
|
||||
(x) => x * 3,
|
||||
(x) => {
|
||||
return {
|
||||
result: x,
|
||||
isOdd: x % 2 === 0,
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
return { reduceCalls, fArr1, fArr2 }
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => eq(findIP(dataSet), $findIP))
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
const dataSet = `qqq http:// qqqq q qqqqq https://something.com/hello qqqqqqq qhttp://example.com/hello?you=something&something=you qq 233.123.12.234 qw w wq wqw wqw ijnjjnfapsdbjnkfsdiqw klfsdjn fs fsd https://devdocs.io/javascript/global_objects/object/fromentries njnkfsdjnk sfdjn fsp fd192.168.1.123:8080 https://devdocs.io/javascript/global_objects/regexp/@@split
|
||||
htpp://wrong/url hello %$& wf* ][½¬ http://correct/url?correct=yes è[}£§ https://nan-academy.github.io/js-training/?page=editor#data.nested 255.256.1233.2
|
||||
ssages has become an accepted part of many cultures, as happened earlier with emailing. htt://[1] This makes texting a quick and http://www.example.com/mypage.html?crcat=test&crsource=test&crkw=buy-a-loteasy way to communicate 255.256.2 with friends, family and colleagues, including 255.256.555.2 in contexts where a call would be when one knows the other person is busy 192.169.1.23 with family or work activities).; 172.01.123.254:1234
|
||||
for example, to order products or 10.1.23.7 http://www_example.com/ 255.255.255.000 09.09.09.09
|
||||
services fromhttps://regex-performance.github.io/exercises.html 3...3 0.0.0.0:22 0.0.0.0:68768
|
||||
this permits communication even between busy individuals255.253.123.2:8000 https: // . Text messages can also http:// be used to http://example.com/path?name=Branch&products=[Journeys,Email,Universal%20Ads]interact with automated systems,https:// regex -performance.github.io/ exercises.html172.01.123.999:1234
|
||||
https//nan-academy.github.io/js-training/?page=editor#data.nested impolite or inappropriate (e.g., calling very late at night orhttp://localhost/exercises
|
||||
https://192.168.1.123?something=nothing&pro=[23] htts:/nan-academy.github.io/js-training?b=123&a=123/?page=editor#data.nested Like e-mail and voicemail and unlike calls (in which the caller hopes to speak directly with the recipient),
|
||||
http://www.example.com/catalog.asp?itemid=232&template=fresh&crcat=ppc&crsource=google&crkw=buy-a-lot texting does not require the caller and recipient to both be free at the same moment0.0.0.0`
|
||||
|
||||
const $findIP = [
|
||||
'233.123.12.234',
|
||||
'192.168.1.123:8080',
|
||||
'192.169.1.23',
|
||||
'10.1.23.7',
|
||||
'0.0.0.0:22',
|
||||
'0.0.0.0:68768',
|
||||
'255.253.123.2:8000',
|
||||
'192.168.1.123',
|
||||
'0.0.0.0',
|
||||
]
|
|
@ -0,0 +1,10 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(({ eq }) => vowels.test('a') && !vowels.test('c'))
|
||||
t(({ eq }) => eq(vowelDots('something'), 'so.me.thi.ng'))
|
||||
t(({ eq }) => eq(vowelDots(''), ''))
|
||||
t(({ eq }) => eq(vowelDots('rhythm'), 'rhythm'))
|
||||
t(({ eq }) => eq(vowelDots('Algorithm'), 'A.lgo.ri.thm'))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,6 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
t(() => !(inequality === inequality))
|
||||
|
||||
Object.freeze(tests)
|
|
@ -0,0 +1,24 @@
|
|||
## Abs(olute)
|
||||
|
||||
### Instruction
|
||||
|
||||
Create a `isPositive` function that takes a number as
|
||||
parameter and return true if the given number is
|
||||
stricly positive, or false otherwise
|
||||
|
||||
Create the `abs` function that takes one number argument
|
||||
and returns its absolute value.
|
||||
You are not allowed to use `Math.abs`, make your own.
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://nan-academy.github.io/js-training/examples/functions.js
|
||||
- https://nan-academy.github.io/js-training/examples/ternary.js
|
||||
- https://devdocs.io/javascript/global_objects/math/abs
|
||||
|
||||
|
||||
### Code provided
|
||||
```js
|
||||
Math.abs = undefined
|
||||
```
|
|
@ -0,0 +1,18 @@
|
|||
## All
|
||||
|
||||
### Instructions
|
||||
|
||||
Create a function `all` that works like `Promise.all` but with objects.
|
||||
(instead of arrays)
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://nan-academy.github.io/js-training/examples/promise.js
|
||||
- https://devdocs.io/javascript/global_objects/promise/all
|
||||
|
||||
|
||||
### Code provided
|
||||
```js
|
||||
Promise.all = undefined
|
||||
```
|
|
@ -0,0 +1,11 @@
|
|||
## Arr
|
||||
|
||||
### Instructions
|
||||
|
||||
Create a constant variable named `arr` that is an array
|
||||
containing the values 4 and '2'
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://nan-academy.github.io/js-training/examples/data-structures.js
|
|
@ -0,0 +1,12 @@
|
|||
## Biggie Smalls
|
||||
|
||||
### Instructions
|
||||
|
||||
Create 2 variables
|
||||
- smalls with the smallest possible number value
|
||||
- biggie with the greatest possible number value
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://devdocs.io/javascript-number/
|
|
@ -0,0 +1,14 @@
|
|||
## Bloody Sunday
|
||||
|
||||
### Instructions
|
||||
|
||||
You were missioned to make the world more productive.
|
||||
Your solution ? no more sundays,
|
||||
you are ask to remove them from the existing calendar.
|
||||
|
||||
So now, a week is 6 days from monday to saturday.
|
||||
|
||||
To prove your point, create a `bloodySunday` function
|
||||
that return what week day the given date is.
|
||||
|
||||
> note that the 01/01/0001 is still a monday.
|
|
@ -0,0 +1,7 @@
|
|||
## Capitalize
|
||||
|
||||
### Instructions
|
||||
|
||||
Create a `capitalize` function that takes a string
|
||||
and transforms it to upper case only for the first letter,
|
||||
and in lowercase for the rest of the string
|
|
@ -0,0 +1,30 @@
|
|||
## Change
|
||||
|
||||
### Instructions
|
||||
|
||||
Create 2 functions:
|
||||
- `get`: a function that takes a key and return the corresponding
|
||||
value from the sourceObject
|
||||
|
||||
- `set`: a function that takes a key and a value update the
|
||||
value for the corresponding property of the sourceObject
|
||||
and return the set value
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://nan-academy.github.io/js-training/examples/functions.js
|
||||
- https://nan-academy.github.io/js-training/examples/data-structures.js
|
||||
- https://nan-academy.github.io/js-training/examples/get.js
|
||||
- https://nan-academy.github.io/js-training/examples/set.js
|
||||
|
||||
|
||||
### Code provided
|
||||
```js
|
||||
const sourceObject = {
|
||||
num: 42,
|
||||
bool: true,
|
||||
str: 'some text',
|
||||
log: console.log,
|
||||
}
|
||||
```
|
|
@ -0,0 +1,9 @@
|
|||
## Chunk
|
||||
|
||||
### Instruction
|
||||
|
||||
Create the `chunk` function that returns an array of elements
|
||||
split into groups the length of the given size.
|
||||
|
||||
If array can't be split evenly,
|
||||
the final chunk will be the remaining elements.
|
|
@ -0,0 +1,13 @@
|
|||
## Circular
|
||||
|
||||
### Instructions
|
||||
|
||||
Create an object named `circular` that has a property named `circular` with
|
||||
itself as the value
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://nan-academy.github.io/js-training/examples/data-structures.js
|
||||
- https://nan-academy.github.io/js-training/examples/get.js
|
||||
- https://nan-academy.github.io/js-training/examples/set.js
|
|
@ -0,0 +1,11 @@
|
|||
## Concat Str
|
||||
|
||||
### Instructions
|
||||
|
||||
Create a `concatStr` function that takes 2 arguments and concatenate them
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://nan-academy.github.io/js-training/examples/functions.js
|
||||
- https://nan-academy.github.io/js-training/examples/operators.js
|
|
@ -0,0 +1,6 @@
|
|||
## Count Leap Years
|
||||
|
||||
### Instructions
|
||||
|
||||
Make a `countLeapYears` functions that takes a date
|
||||
and returns the number of leap years since year 1
|
|
@ -0,0 +1,21 @@
|
|||
## Currify
|
||||
|
||||
### Instructions
|
||||
|
||||
Create the function `currify` that will curry any functions put as argument.
|
||||
|
||||
example:
|
||||
```js
|
||||
const mult2 = (el1,el2) => el1 * el2
|
||||
console.log(mult2(2,2)) // result epected 4
|
||||
|
||||
|
||||
const mult2Curried = currify(mult2)
|
||||
|
||||
console.log(mult2Curried(2)(2)) // result expected 4
|
||||
// (same result, with a function that has technically only one argument)
|
||||
```
|
||||
|
||||
### Notions
|
||||
|
||||
- https://stackoverflow.com/questions/36314/what-is-currying
|
|
@ -0,0 +1,45 @@
|
|||
## curry entries
|
||||
|
||||
### Instruction
|
||||
|
||||
This exercise consists in creating curry functions to apply in the objects
|
||||
entries.
|
||||
You will have to create the following curry functions:
|
||||
|
||||
- `defaultCurry` that will curry two objects in witch the second object must
|
||||
be the default object and returns a new object with the modifications applied
|
||||
by the first object
|
||||
- `mapCurry` that replicate the function `.map`
|
||||
- `reduceCurry` that replicate the function `.reduce`
|
||||
- `filterCurry` that replicate the function `.filter`
|
||||
|
||||
You will also have to create for each curry function the following:
|
||||
|
||||
- `reduceScore` that will return the total value of the scores
|
||||
of the persons who use the force
|
||||
- `filterForce` that will return the force users with `shootingScores`
|
||||
equal or higher than 80
|
||||
- `mapAverage` that will return a new object with the propriety `averageScore`
|
||||
that is the averages of the scores for each person
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://devdocs.io/javascript/global_objects/array/filter
|
||||
- https://devdocs.io/javascript/global_objects/array/map
|
||||
- https://devdocs.io/javascript/global_objects/array/reduce
|
||||
- https://devdocs.io/javascript/global_objects/object/entries
|
||||
- https://devdocs.io/javascript/global_objects/object/fromentries
|
||||
|
||||
|
||||
### Code provided
|
||||
```js
|
||||
// prettier-ignore
|
||||
const personnel = {
|
||||
lukeSkywalker: { id: 5, pilotingScore: 98, shootingScore: 56, isForceUser: true },
|
||||
sabineWren: { id: 82, pilotingScore: 73, shootingScore: 99, isForceUser: false },
|
||||
zebOrellios: { id: 22, pilotingScore: 20, shootingScore: 59, isForceUser: false },
|
||||
ezraBridger: { id: 15, pilotingScore: 43, shootingScore: 67, isForceUser: true },
|
||||
calebDume: { id: 11, pilotingScore: 71, shootingScore: 85, isForceUser: true },
|
||||
}
|
||||
```
|
|
@ -0,0 +1,24 @@
|
|||
## Cut corners
|
||||
|
||||
### Instructions
|
||||
|
||||
Create a function for each rounding math functions:
|
||||
- round (like `Math.round`)
|
||||
- ceil (like `Math.ceil`)
|
||||
- floor (like `Math.floor`)
|
||||
- trunc (like `Math.trunc`)
|
||||
|
||||
Some restrictions apply:
|
||||
- You may not use strings conversion to do it
|
||||
- No bitwise operator
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://devdocs.io/javascript/global_objects/math
|
||||
|
||||
|
||||
### Code provided
|
||||
```js
|
||||
Math.round = Math.ceil = Math.floor = Math.trunc = undefined
|
||||
```
|
|
@ -0,0 +1,6 @@
|
|||
## Day of the Year
|
||||
|
||||
### Instructions
|
||||
|
||||
Make a `dayOfTheYear` functions that takes a date
|
||||
and returns the number of days since the first day of that year
|
|
@ -0,0 +1,11 @@
|
|||
## debouncing
|
||||
|
||||
## Instruction
|
||||
|
||||
Create two functions that will work like `_.debounce` from lodash
|
||||
- `debounce`, this function doesn't need to take care of the options
|
||||
- `opDebounce`, this function will take care of the `leading` options
|
||||
|
||||
### Notions
|
||||
|
||||
- https://lodash.com/docs/4.17.15#debounce
|
|
@ -0,0 +1,9 @@
|
|||
## deep-copy
|
||||
|
||||
### Instructions
|
||||
|
||||
Create a function called `deepCopy` that copy objects and arrays recursively.
|
||||
|
||||
### Notions
|
||||
|
||||
- https://devdocs.io/javascript-object/
|
|
@ -0,0 +1,14 @@
|
|||
## Elementary
|
||||
|
||||
### Instructions
|
||||
|
||||
Create 3 functions:
|
||||
- `multiply` that act like the `*` operator without using it
|
||||
- `divide` that do an integer division without using `/`
|
||||
- `modulo` that act like the `%` operator without using it
|
||||
|
||||
|
||||
### Code provided
|
||||
```js
|
||||
Math.imul = undefined
|
||||
```
|
|
@ -0,0 +1,17 @@
|
|||
## Escape Str
|
||||
|
||||
### Instructions
|
||||
|
||||
Create a constant variable named `escapeStr` that contains
|
||||
the following specials characters:
|
||||
- `
|
||||
- \
|
||||
- /
|
||||
- "
|
||||
- '
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- Primitive and Operators
|
||||
- Variables
|
|
@ -0,0 +1,25 @@
|
|||
### Instruction
|
||||
|
||||
Create a function called `findExpression` that takes a number as parameter and returns a string
|
||||
|
||||
- It will be given two constant variable `add4` and `mul2`
|
||||
|
||||
- Your goal is to try to find a sequence, starting from the number 1, and repeatedly either adding 4 or multiplying 2
|
||||
that produces the number given has parameter.
|
||||
For example, the number 8 you must first multiplying by 2 twice and then add 4.
|
||||
It will look something like this `1 *2 *2 +4`
|
||||
|
||||
- If the number can not be reached you should return `undefined`
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://nan-academy.github.io/js-training/examples/loops.js
|
||||
- https://nan-academy.github.io/js-training/examples/recursion.js
|
||||
|
||||
|
||||
### Code provided
|
||||
```js
|
||||
const add4 = '+4'
|
||||
const mul2 = '*2'
|
||||
```
|
|
@ -0,0 +1,30 @@
|
|||
## flags
|
||||
|
||||
### Instruction
|
||||
|
||||
Create a function called `flags` that receives an object and outputs
|
||||
the specific aliases and descriptions from the properties of that object.
|
||||
|
||||
The `help` flag:
|
||||
- Should be present in the output by default.
|
||||
- When not present in the input, it should output the description of all flags.
|
||||
But when present it can specify the flags that you want to see
|
||||
the description of. (ex: `help: ['divide']`)
|
||||
|
||||
#### Example:
|
||||
|
||||
```js
|
||||
{
|
||||
multiply: 'multiply the values',
|
||||
divide: 'divides the values',
|
||||
help: ['divide']
|
||||
}
|
||||
```
|
||||
and outputs :
|
||||
|
||||
```js
|
||||
{
|
||||
alias: { h: 'help', m: 'multiply', d: 'divide'}
|
||||
description: '-d, --divide: divides the values',
|
||||
}
|
||||
```
|
|
@ -0,0 +1,16 @@
|
|||
## Flat
|
||||
|
||||
### Instructions
|
||||
|
||||
Create the `flat` functions that works like the `.flat` array method
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://devdocs.io/javascript/global_objects/array/flat
|
||||
|
||||
|
||||
### Code provided
|
||||
```js
|
||||
Array.prototype.flat = undefined
|
||||
```
|
|
@ -0,0 +1,28 @@
|
|||
## Flow
|
||||
|
||||
### Instructions
|
||||
|
||||
Create the function `flow` that will works as the _.flow([funcs])
|
||||
from lodash.
|
||||
|
||||
Example
|
||||
|
||||
``` js
|
||||
|
||||
const square = nbr => nbr * nbr
|
||||
const add2Numbers = (nbr1, nbr2) => nbr1 + nbr2
|
||||
|
||||
const flowedFunctions = flow([add2numbers, square])
|
||||
flowedFunctions(2, 3)
|
||||
|
||||
```
|
||||
|
||||
returns
|
||||
|
||||
```js
|
||||
25
|
||||
```
|
||||
|
||||
### Notions
|
||||
|
||||
- https://lodash.com/docs/4.17.15#flow
|
|
@ -0,0 +1,13 @@
|
|||
## fusion
|
||||
|
||||
### Instructions
|
||||
|
||||
The objective of this exercise is to merge objects into a new object depending on the values type
|
||||
|
||||
With this create a function called `fusion` that:
|
||||
- If the type is an array you must concat it
|
||||
- If it is a string you must concatenate with a space
|
||||
- If it is numbers you must added them
|
||||
- If it is an object you must fusion them recursively
|
||||
- In case of other types you must replace it with the value of the second object
|
||||
- In case the value don't match you must replace it with the value of the second object
|
|
@ -0,0 +1,12 @@
|
|||
## Get Length
|
||||
|
||||
### Instructions
|
||||
|
||||
Create a `getLength` function that takes an array or a string
|
||||
and return its length.
|
||||
|
||||
|
||||
### Notions
|
||||
|
||||
- https://nan-academy.github.io/js-training/examples/data-structures.js
|
||||
- https://nan-academy.github.io/js-training/examples/get.js
|
|
@ -0,0 +1,10 @@
|
|||
## Get
|
||||
|
||||
### Instructions
|
||||
|
||||
Create the `get` function.
|
||||
It takes 2 arguments:
|
||||
- `src` an object
|
||||
- `path` a string
|
||||
|
||||
And returns the value at the given string path.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue