mirror of https://github.com/01-edu/public.git
moving js test comments for students
This commit is contained in:
parent
5bc89b1230
commit
498fdd9897
|
@ -3,45 +3,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 }) =>
|
||||
// it should work with an empty object
|
||||
eq(await all({}), {})
|
||||
)
|
||||
|
||||
t(async ({ eq }) =>
|
||||
// it should work with synchronous values
|
||||
eq(await all({ a: 1, b: true }), { a: 1, b: true })
|
||||
)
|
||||
|
||||
t(async ({ eq }) =>
|
||||
// it should work with pending promises
|
||||
eq(
|
||||
await all({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.resolve(true),
|
||||
}),
|
||||
{ a: 1, b: true },
|
||||
),
|
||||
{ a: 1, b: true }
|
||||
)
|
||||
)
|
||||
|
||||
// it should work with pending promises and synchronous values
|
||||
t(async ({ eq, ctx }) =>
|
||||
// it should work with pending promises and synchronous values
|
||||
eq(
|
||||
await all(
|
||||
Object.freeze({
|
||||
a: Promise.resolve(ctx).then((v) => v + 1),
|
||||
b: ctx,
|
||||
}),
|
||||
})
|
||||
),
|
||||
{ a: ctx + 1, b: ctx },
|
||||
),
|
||||
{ a: ctx + 1, b: ctx }
|
||||
)
|
||||
)
|
||||
|
||||
// it should fail if one of the promises reject
|
||||
t(async ({ eq }) =>
|
||||
// it should fail if one of the promises reject
|
||||
eq(
|
||||
await all({
|
||||
a: Promise.resolve(1),
|
||||
b: Promise.reject(Error('oops')),
|
||||
}).catch((err) => err.message),
|
||||
'oops',
|
||||
),
|
||||
'oops'
|
||||
)
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
|
|
@ -16,43 +16,44 @@ const run = (callback, { delay, count }) =>
|
|||
}, 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 }) =>
|
||||
// test with debounce wait limit inferior to wait time call (how much time we wait to the function be called again)
|
||||
// it works concurrently
|
||||
eq(
|
||||
await Promise.all([
|
||||
run(debounce(add, 5), { delay: 10, count: 5 }),
|
||||
run(debounce(add, 2), { delay: 5, count: 10 }),
|
||||
]),
|
||||
[4, 9],
|
||||
),
|
||||
[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 }) =>
|
||||
// testing with wait limit superior to wait time call
|
||||
// execution on the trailing edge, after wait limit has elapsed
|
||||
eq(await run(debounce(add, 10), { delay: 5, count: 5 }), 0)
|
||||
)
|
||||
|
||||
t(async ({ eq }) =>
|
||||
// it works concurrently
|
||||
eq(
|
||||
await Promise.all([
|
||||
run(opDebounce(add, 4), { delay: 2, count: 5 }),
|
||||
run(opDebounce(add, 4), { delay: 2, count: 2 }),
|
||||
]),
|
||||
[0, 0],
|
||||
),
|
||||
[0, 0]
|
||||
)
|
||||
)
|
||||
|
||||
// leading edge as true
|
||||
// it works concurrently
|
||||
t(async ({ eq }) =>
|
||||
// leading edge as true
|
||||
// it works concurrently
|
||||
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],
|
||||
),
|
||||
[1, 3]
|
||||
)
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
|
|
@ -1,29 +1,43 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// simple object
|
||||
t(({ eq }) => copyAndCompare(eq, { user: 'mika', age: 37 }))
|
||||
t(({ eq }) =>
|
||||
// simple object
|
||||
copyAndCompare(eq, { user: 'mika', age: 37 })
|
||||
)
|
||||
|
||||
// simple array
|
||||
t(({ eq }) => copyAndCompare(eq, [1, 'a']))
|
||||
t(({ eq }) =>
|
||||
// simple array
|
||||
copyAndCompare(eq, [1, 'a'])
|
||||
)
|
||||
|
||||
// works with any value type
|
||||
t(({ eq }) => copyAndCompare(eq, [console.log, /hello/]))
|
||||
t(({ eq }) =>
|
||||
// works with any value type
|
||||
copyAndCompare(eq, [console.log, /hello/])
|
||||
)
|
||||
|
||||
// nesting object
|
||||
t(({ eq }) => copyAndCompare(eq, { a: { b: { c: 1 } } }))
|
||||
t(({ eq }) =>
|
||||
// nesting object
|
||||
copyAndCompare(eq, { a: { b: { c: 1 } } })
|
||||
)
|
||||
|
||||
// nesting array
|
||||
t(({ eq }) => copyAndCompare(eq, [1, [2, [true]]]))
|
||||
t(({ eq }) =>
|
||||
// nesting array
|
||||
copyAndCompare(eq, [1, [2, [true]]])
|
||||
)
|
||||
|
||||
// mixed nesting
|
||||
t(({ eq }) => copyAndCompare(eq, [{ a: () => {} }, ['b', { b: [3] }]]))
|
||||
t(({ eq }) =>
|
||||
// mixed nesting
|
||||
copyAndCompare(eq, [{ a: () => {} }, ['b', { b: [3] }]])
|
||||
)
|
||||
|
||||
// undefined value
|
||||
t(({ eq }) => copyAndCompare(eq, { undef: undefined }))
|
||||
t(({ eq }) =>
|
||||
// undefined value
|
||||
copyAndCompare(eq, { undef: undefined })
|
||||
)
|
||||
|
||||
// check deep freeze (caution: might stuns a target for 4 seconds)
|
||||
t(({ eq }) => {
|
||||
// check deep freeze (caution: might stuns a target for 4 seconds)
|
||||
const r = Math.random()
|
||||
const obj = [r, Object.freeze([r, Object.freeze([r])])]
|
||||
const copy = deepCopy(obj)
|
||||
|
|
|
@ -27,8 +27,8 @@ t(() => addWeek(new Date('1995-11-07')) === 'Tuesday')
|
|||
t(() => addWeek(new Date('2020-01-01')) === 'Wednesday')
|
||||
t(() => addWeek(new Date('2048-12-07')) === 'Monday')
|
||||
|
||||
// random time traveling
|
||||
t(({ eq }) =>
|
||||
// random time traveling
|
||||
eq(
|
||||
timeTravel({
|
||||
date: new Date('2020-05-29 23:25:22'),
|
||||
|
|
|
@ -9,22 +9,22 @@ export const setup = () => {
|
|||
return { arr }
|
||||
}
|
||||
|
||||
// callback is call with the item value
|
||||
t(({ eq, ctx }) => {
|
||||
// callback is call with the item value
|
||||
const result = []
|
||||
forEach(ctx.arr, (value) => result.push(value))
|
||||
return eq(result, ctx.arr)
|
||||
})
|
||||
|
||||
// callback second parameter is the index
|
||||
t(({ eq, ctx }) => {
|
||||
// callback second parameter is the index
|
||||
const result = []
|
||||
forEach(ctx.arr, (_, index) => result.push(index))
|
||||
return eq(result, [...ctx.arr.keys()])
|
||||
})
|
||||
|
||||
// callback third parameter is the array
|
||||
t(({ eq, ctx }) => {
|
||||
// callback third parameter is the array
|
||||
const result = []
|
||||
forEach(ctx.arr, (_, __, arr) => result.push(arr))
|
||||
return eq(result, Array(ctx.arr.length).fill(ctx.arr))
|
||||
|
|
|
@ -8,38 +8,44 @@ t(({ eq }) => eq(fusion({ nbr: 12 }, { nbr: 23 }).nbr, 35))
|
|||
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 }),
|
||||
// multiply numbers
|
||||
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 }) =>
|
||||
// simple string
|
||||
eq(fusion({ str: 'hello' }, { str: 'there' }).str, 'hello there')
|
||||
)
|
||||
|
||||
t(({ eq }) =>
|
||||
// handle empty strings
|
||||
eq(fusion({ str: 'hello' }, { str: '' }).str, 'hello ')
|
||||
)
|
||||
|
||||
t(({ eq }) =>
|
||||
// multiple strings
|
||||
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 }) =>
|
||||
// simple arrays
|
||||
eq(fusion({ arr: [1, '2'] }, { arr: [2] }).arr, [1, '2', 2])
|
||||
)
|
||||
|
||||
t(({ eq }) =>
|
||||
// multiple arrays
|
||||
eq(
|
||||
fusion(
|
||||
{ arr: [], arr1: [1] },
|
||||
{ arr: [12, 3], arr1: [2, 3], arr2: ['2', '1'] },
|
||||
{ arr: [12, 3], arr1: [2, 3], arr2: ['2', '1'] }
|
||||
),
|
||||
{ arr: [12, 3], arr1: [1, 2, 3], arr2: ['2', '1'] },
|
||||
),
|
||||
{ arr: [12, 3], arr1: [1, 2, 3], arr2: ['2', '1'] }
|
||||
)
|
||||
)
|
||||
|
||||
// different matching
|
||||
|
@ -48,23 +54,23 @@ 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 }) =>
|
||||
// deep nested objects
|
||||
eq(
|
||||
fusion(
|
||||
{ a: { b: [1, 2], c: { d: 2 } } },
|
||||
{ a: { b: [0, 2, 1], c: { d: 23 } } },
|
||||
{ a: { b: [0, 2, 1], c: { d: 23 } } }
|
||||
),
|
||||
{ a: { b: [1, 2, 0, 2, 1], c: { d: 25 } } },
|
||||
),
|
||||
{ a: { b: [1, 2, 0, 2, 1], c: { d: 25 } } }
|
||||
)
|
||||
)
|
||||
|
||||
// object mutability
|
||||
t(({ eq }) =>
|
||||
// object mutability
|
||||
eq(
|
||||
fusion(Object.freeze({ a: { b: 1 } }), Object.freeze({ a: { b: 2 } })).a.b,
|
||||
3,
|
||||
),
|
||||
3
|
||||
)
|
||||
)
|
||||
|
||||
// other types
|
||||
|
|
|
@ -10,60 +10,60 @@ const fakeFetch = async ({ data, error, ...opts } = {}) => ({
|
|||
...opts,
|
||||
})
|
||||
|
||||
// check url parsing
|
||||
t(async ({ eq }) => {
|
||||
// check url parsing
|
||||
let url
|
||||
fetch = async (arg) => fakeFetch({ url: (url = arg) })
|
||||
const pending = getJSON('/test', { query: 'hello world', b: 5 })
|
||||
return eq(url, '/test?query=hello%20world&b=5')
|
||||
})
|
||||
|
||||
// check that it return the given value
|
||||
t(async ({ eq }) => {
|
||||
// check that it return the given value
|
||||
const data = Math.random()
|
||||
fetch = (url) => fakeFetch({ url, data })
|
||||
return eq(await getJSON('/', { q: 1 }), data)
|
||||
})
|
||||
|
||||
// check that it throw an error with the correct message
|
||||
t(async ({ eq }) => {
|
||||
// check that it throw an error with the correct message
|
||||
const error = `oops: ${Math.random()}`
|
||||
fetch = (url) => fakeFetch({ url, error })
|
||||
|
||||
return eq(
|
||||
await getJSON('/', { q: 1 }).then(
|
||||
() => Promise.reject(Error('Should fail')),
|
||||
(err) => err.message,
|
||||
(err) => err.message
|
||||
),
|
||||
error,
|
||||
error
|
||||
)
|
||||
})
|
||||
|
||||
// check that it throw if the request is not ok
|
||||
t(async ({ eq }) => {
|
||||
// check that it throw if the request is not ok
|
||||
fetch = (url) =>
|
||||
fakeFetch({ url, status: 500, statusText: 'Internal Server Error' })
|
||||
|
||||
return eq(
|
||||
await getJSON('/', { q: 1 }).then(
|
||||
() => Promise.reject(Error('Should fail')),
|
||||
(err) => err.message,
|
||||
(err) => err.message
|
||||
),
|
||||
'Internal Server Error',
|
||||
'Internal Server Error'
|
||||
)
|
||||
})
|
||||
|
||||
// if fetch fail, the error should not be handled
|
||||
t(async ({ eq }) => {
|
||||
// if fetch fail, the error should not be handled
|
||||
const error = `oops: ${Math.random()}`
|
||||
fetch = (url) => Promise.reject(Error(error))
|
||||
|
||||
return eq(
|
||||
await getJSON('/', { q: 1 }).then(
|
||||
() => Promise.reject(Error('Should fail')),
|
||||
(err) => err.message,
|
||||
(err) => err.message
|
||||
),
|
||||
error,
|
||||
error
|
||||
)
|
||||
})
|
||||
|
||||
|
|
|
@ -4,20 +4,20 @@ let getJSON = async (url) => url
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// queryServers with main server be fastest
|
||||
t(async ({ eq, ctx }) => {
|
||||
// queryServers with main server be fastest
|
||||
ctx.setTimings({ pouet_backup: 2 })
|
||||
return eq(await queryServers('pouet', ctx.r), `/pouet?q=${ctx.r}`)
|
||||
})
|
||||
|
||||
// queryServers with backup server be fastest
|
||||
t(async ({ eq, ctx }) => {
|
||||
// queryServers with backup server be fastest
|
||||
ctx.setTimings({ pouet: 2 })
|
||||
return eq(await queryServers('pouet', ctx.r), `/pouet_backup?q=${ctx.r}`)
|
||||
})
|
||||
|
||||
// gougleSearch fast enough
|
||||
t(async ({ eq, ctx }) => {
|
||||
// gougleSearch fast enough
|
||||
ctx.setTimings({ web_backup: 3, image: 2, video_backup: 4 })
|
||||
return eq(await gougleSearch(ctx.r), {
|
||||
web: `/web?q=${ctx.r}`,
|
||||
|
@ -26,8 +26,8 @@ t(async ({ eq, ctx }) => {
|
|||
})
|
||||
})
|
||||
|
||||
// gougleSearch fast enough, alternate timings
|
||||
t(async ({ eq, ctx }) => {
|
||||
// gougleSearch fast enough, alternate timings
|
||||
ctx.setTimings({ web: 3, image_backup: 1, video: 4 })
|
||||
return eq(await gougleSearch(ctx.r), {
|
||||
web: `/web_backup?q=${ctx.r}`,
|
||||
|
@ -36,15 +36,15 @@ t(async ({ eq, ctx }) => {
|
|||
})
|
||||
})
|
||||
|
||||
// gougleSearch too slow !
|
||||
t(async ({ eq, ctx }) => {
|
||||
// gougleSearch too slow !
|
||||
ctx.setTimings({ web: 85, web_backup: 99 })
|
||||
return eq(
|
||||
await gougleSearch(ctx.r).then(
|
||||
() => Promise.reject(Error('Should fail')),
|
||||
(err) => err.message,
|
||||
(err) => err.message
|
||||
),
|
||||
'timeout',
|
||||
'timeout'
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -55,6 +55,6 @@ export const setup = () => ({
|
|||
setTimings: (timings) =>
|
||||
(getJSON = (url) =>
|
||||
new Promise((s) =>
|
||||
setTimeout(s, timings[url.split(/\/([^?]+)?/)[1]] || 0, url),
|
||||
setTimeout(s, timings[url.split(/\/([^?]+)?/)[1]] || 0, url)
|
||||
)),
|
||||
})
|
||||
|
|
|
@ -10,14 +10,14 @@ const run = async ({ step, start, end, duration, waitTime = 15 }) => {
|
|||
return arr
|
||||
}
|
||||
|
||||
// testing duration time, forbid loops
|
||||
t(async ({ eq }) => {
|
||||
// testing duration time, forbid loops
|
||||
const { length } = await run({ step: 5, start: 0, end: 4, duration: 28 })
|
||||
return eq(length, 2)
|
||||
})
|
||||
|
||||
// testing duration time stamp
|
||||
t(async ({ eq }) => {
|
||||
// testing duration time stamp
|
||||
const { length } = await run({
|
||||
step: 5,
|
||||
start: 0,
|
||||
|
@ -28,34 +28,34 @@ t(async ({ eq }) => {
|
|||
return eq(length, 0)
|
||||
})
|
||||
|
||||
// testing the amount of times the callback was called
|
||||
t(async ({ eq }) => {
|
||||
// testing the amount of times the callback was called
|
||||
const { length } = await run({ step: 5, start: 0, end: 1, duration: 10 })
|
||||
return eq(length, 5)
|
||||
})
|
||||
|
||||
// testing the interpolation points
|
||||
t(async ({ eq }) =>
|
||||
// testing the interpolation points
|
||||
eq(await run({ step: 5, start: 0, end: 1, duration: 10 }), [
|
||||
[0, 2],
|
||||
[0.2, 4],
|
||||
[0.4, 6],
|
||||
[0.6, 8],
|
||||
[0.8, 10],
|
||||
]),
|
||||
])
|
||||
)
|
||||
|
||||
// testing with different values
|
||||
t(async ({ eq }) =>
|
||||
// testing with different values
|
||||
eq(await run({ step: 3, start: 1, end: 2, duration: 10 }), [
|
||||
[1, 3.33],
|
||||
[1.33, 6.67],
|
||||
[1.67, 10],
|
||||
]),
|
||||
])
|
||||
)
|
||||
|
||||
// testing with `duration` inferior to `step`
|
||||
t(async ({ eq }) =>
|
||||
// testing with `duration` inferior to `step`
|
||||
eq(await run({ step: 10, start: 2, end: 6, duration: 4 }), [
|
||||
[2, 0.4],
|
||||
[2.4, 0.8],
|
||||
|
@ -67,19 +67,19 @@ t(async ({ eq }) =>
|
|||
[4.8, 3.2],
|
||||
[5.2, 3.6],
|
||||
[5.6, 4],
|
||||
]),
|
||||
])
|
||||
)
|
||||
|
||||
// testing with `start` superior to `end`
|
||||
// inverted straight line
|
||||
t(async ({ eq }) =>
|
||||
// testing with `start` superior to `end`
|
||||
// inverted straight line
|
||||
eq(await run({ step: 5, start: 6, end: 2, duration: 6, waitTime: 10 }), [
|
||||
[6, 1.2],
|
||||
[5.2, 2.4],
|
||||
[4.4, 3.6],
|
||||
[3.6, 4.8],
|
||||
[2.8, 6],
|
||||
]),
|
||||
])
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
|
|
@ -10,11 +10,11 @@ t(({ eq }) =>
|
|||
John: 'firstName',
|
||||
Doe: 'lastName',
|
||||
32: 'age',
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
// Last similar value should override the others
|
||||
t(({ eq }) =>
|
||||
// Last similar value should override the others
|
||||
eq(
|
||||
invert({ brand: 'ford', motor: 'v8', year: 2000, fast: true, eco: true }),
|
||||
{
|
||||
|
@ -22,11 +22,13 @@ t(({ eq }) =>
|
|||
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' }))
|
||||
t(({ eq }) =>
|
||||
// It should ignore properties from the prototype chain
|
||||
eq(invert({ f: 5, __proto__: { d: 6 } }), { 5: 'f' })
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
|
|
@ -57,52 +57,54 @@ const db = (() => {
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// testing correct continent but wrong number of times
|
||||
t(async ({ eq }) =>
|
||||
// testing correct continent but wrong number of times
|
||||
eq(
|
||||
await isWinner('England'),
|
||||
'England is not what we are looking for because of the number of times it was champion',
|
||||
),
|
||||
'England is not what we are looking for because of the number of times it was champion'
|
||||
)
|
||||
)
|
||||
|
||||
// testing non winner country
|
||||
t(async ({ eq }) =>
|
||||
eq(await isWinner('Colombia'), 'Colombia never was a winner'),
|
||||
// testing non winner country
|
||||
eq(await isWinner('Colombia'), 'Colombia never was a winner')
|
||||
)
|
||||
|
||||
// testing wrong continent country
|
||||
t(async ({ eq }) =>
|
||||
// testing wrong continent country
|
||||
eq(
|
||||
await isWinner('Uruguay'),
|
||||
'Uruguay is not what we are looking for because of the continent',
|
||||
),
|
||||
'Uruguay is not what we are looking for because of the continent'
|
||||
)
|
||||
)
|
||||
|
||||
// testing no country
|
||||
t(async ({ eq }) => eq(await isWinner(''), ' never was a winner'))
|
||||
|
||||
// testing correct number of times but wrong continent
|
||||
t(async ({ eq }) =>
|
||||
// testing no country
|
||||
eq(await isWinner(''), ' never was a winner')
|
||||
)
|
||||
|
||||
t(async ({ eq }) =>
|
||||
// testing correct number of times but wrong continent
|
||||
eq(
|
||||
await isWinner('Brazil'),
|
||||
'Brazil is not what we are looking for because of the continent',
|
||||
),
|
||||
'Brazil is not what we are looking for because of the continent'
|
||||
)
|
||||
)
|
||||
|
||||
// testing correct number of times and correct continent
|
||||
t(async ({ eq }) =>
|
||||
// testing correct number of times and correct continent
|
||||
eq(
|
||||
await isWinner('Germany'),
|
||||
'Germany won the FIFA World Cup in 1954, 1974, 1990, 2014 winning by 3-2, 2-1, 1-0, 1-0',
|
||||
),
|
||||
'Germany won the FIFA World Cup in 1954, 1974, 1990, 2014 winning by 3-2, 2-1, 1-0, 1-0'
|
||||
)
|
||||
)
|
||||
|
||||
// testing correct number of times and correct continent, for the fake country
|
||||
t(async ({ eq, ctx }) =>
|
||||
// testing correct number of times and correct continent, for the fake country
|
||||
eq(
|
||||
await isWinner(ctx.name),
|
||||
`${ctx.name} won the FIFA World Cup in 2022, 2026, 2030 winning by 1-0, 3-1, 2-1`,
|
||||
),
|
||||
`${ctx.name} won the FIFA World Cup in 2022, 2026, 2030 winning by 1-0, 3-1, 2-1`
|
||||
)
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
|
|
@ -4,17 +4,16 @@ const t = (f) => tests.push(f)
|
|||
// empty dataset
|
||||
t(({ eq }) => eq(neuron([]), {}))
|
||||
|
||||
// simple dataset
|
||||
t(({ eq }) =>
|
||||
// simple dataset
|
||||
eq(
|
||||
neuron(['Orders: shutdown please! - Response: no!']).orders
|
||||
.shutdown_please,
|
||||
{ order: 'shutdown please!', responses: ['no!'] },
|
||||
),
|
||||
neuron(['Orders: shutdown please! - Response: no!']).orders.shutdown_please,
|
||||
{ order: 'shutdown please!', responses: ['no!'] }
|
||||
)
|
||||
)
|
||||
|
||||
// multiple questions
|
||||
t(({ eq }) =>
|
||||
// multiple questions
|
||||
eq(
|
||||
neuron([
|
||||
'Questions: what is life? - Response: The condition that distinguishes animals and plants from inorganic matter',
|
||||
|
@ -26,12 +25,12 @@ t(({ eq }) =>
|
|||
'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 }) =>
|
||||
// multiple interactions
|
||||
eq(
|
||||
neuron([
|
||||
'Questions: how are you? - Response: well thanks, and you?',
|
||||
|
@ -39,12 +38,12 @@ t(({ eq, ctx }) =>
|
|||
'affirmations: i am fine - Response: awesome',
|
||||
'Orders: turn on the lights! - Response: done',
|
||||
]),
|
||||
ctx.multiInteractions,
|
||||
),
|
||||
ctx.multiInteractions
|
||||
)
|
||||
)
|
||||
|
||||
// out of order
|
||||
t(({ eq, ctx }) =>
|
||||
// out of order
|
||||
eq(
|
||||
neuron([
|
||||
'Questions: how are you? - Response: well thanks, and you?',
|
||||
|
@ -52,12 +51,14 @@ t(({ eq, ctx }) =>
|
|||
'Orders: turn on the lights! - Response: done',
|
||||
'affirmations: i am fine - Response: awesome',
|
||||
]),
|
||||
ctx.multiInteractions,
|
||||
),
|
||||
ctx.multiInteractions
|
||||
)
|
||||
)
|
||||
|
||||
// testing big dataset
|
||||
t(({ eq, ctx }) => eq(neuron(ctx.multipleTypes), ctx.multResult))
|
||||
t(({ eq, ctx }) =>
|
||||
// testing big dataset
|
||||
eq(neuron(ctx.multipleTypes), ctx.multResult)
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// no pronouns
|
||||
t(({ eq }) =>
|
||||
// no pronouns
|
||||
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 }) =>
|
||||
// simple count
|
||||
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
|
||||
|
@ -20,39 +20,39 @@ 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 }) =>
|
||||
// multiple pronouns
|
||||
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 }) =>
|
||||
// repetition of pronouns
|
||||
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 } }),
|
||||
// repetition of same pronoun
|
||||
eq(pronoun('she she she she is'), { she: { word: ['is'], count: 4 } })
|
||||
)
|
||||
|
||||
// pronoun with out verb
|
||||
t(({ eq }) =>
|
||||
// pronoun with out verb
|
||||
eq(pronoun('we will rock you'), {
|
||||
we: { word: ['will'], count: 1 },
|
||||
you: { word: [], count: 1 },
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
|
|
@ -4,62 +4,66 @@ export const tests = []
|
|||
const t = (f) => tests.push(f)
|
||||
|
||||
//// RACE
|
||||
// empty array should never resolve, just hang, forever...
|
||||
t(async ({ eq, wait }) => {
|
||||
// empty array should never resolve, just hang, forever...
|
||||
let notCalled = true
|
||||
race([]).then(() => (notCalled = false))
|
||||
await wait(5)
|
||||
return eq(notCalled, true)
|
||||
})
|
||||
|
||||
// it should return the first value to resolve
|
||||
t(async ({ eq, wait }) =>
|
||||
eq(await race([Promise.resolve(2), wait(5).then(() => 5)]), 2),
|
||||
// it should return the first value to resolve
|
||||
eq(await race([Promise.resolve(2), wait(5).then(() => 5)]), 2)
|
||||
)
|
||||
|
||||
// it should not wait for every results to wait
|
||||
t(async ({ eq, wait }) => {
|
||||
// it should not wait for every results to wait
|
||||
const start = Date.now()
|
||||
const result = await race([Promise.resolve(2), wait(50)])
|
||||
if (Date.now() - start > 5) throw Error("that's too long !")
|
||||
return eq(result, 2)
|
||||
})
|
||||
|
||||
// it should fail if the first promise reject
|
||||
t(async ({ eq, wait }) =>
|
||||
// it should fail if the first promise reject
|
||||
eq(
|
||||
await race([wait(5), Promise.reject(Error('oops'))]).catch(
|
||||
(err) => err.message,
|
||||
(err) => err.message
|
||||
),
|
||||
'oops',
|
||||
),
|
||||
'oops'
|
||||
)
|
||||
)
|
||||
|
||||
// it should not fail if the first promise did not reject
|
||||
t(async ({ eq, wait, ctx }) =>
|
||||
// it should not fail if the first promise did not reject
|
||||
eq(
|
||||
await race([
|
||||
wait(5).then(() => Promise.reject(Error('oops'))),
|
||||
Promise.resolve(ctx),
|
||||
]).catch((err) => err.message),
|
||||
ctx,
|
||||
),
|
||||
ctx
|
||||
)
|
||||
)
|
||||
|
||||
//// SOME
|
||||
// empty array returns an empty array
|
||||
t(async ({ eq }) => eq(await some([], 10), []))
|
||||
|
||||
// a count of less than 1 also returns an empty array
|
||||
t(async ({ eq }) => eq(await some([1, 2, 3], 0), []))
|
||||
|
||||
// it should return the first value to resolve
|
||||
t(async ({ eq, wait }) =>
|
||||
eq(await some([Promise.resolve(2), wait(5).then(() => 5)], 1), [2]),
|
||||
t(async ({ eq }) =>
|
||||
// empty array returns an empty array
|
||||
eq(await some([], 10), [])
|
||||
)
|
||||
|
||||
t(async ({ eq }) =>
|
||||
// a count of less than 1 also returns an empty array
|
||||
eq(await some([1, 2, 3], 0), [])
|
||||
)
|
||||
|
||||
t(async ({ eq, wait }) =>
|
||||
// it should return the first value to resolve
|
||||
eq(await some([Promise.resolve(2), wait(5).then(() => 5)], 1), [2])
|
||||
)
|
||||
|
||||
// it should not wait for every results to wait, the order should be preserved.
|
||||
t(async ({ eq, wait }) => {
|
||||
// it should not wait for every results to wait, the order should be preserved.
|
||||
const start = Date.now()
|
||||
const result = await some([wait(1), wait(50), Promise.resolve(5)], 2)
|
||||
if (Date.now() - start > 5) throw Error("that's too long !")
|
||||
|
|
|
@ -1,64 +1,72 @@
|
|||
export const tests = []
|
||||
const t = (f) => tests.push(f)
|
||||
|
||||
// objects mutability
|
||||
t(({ eq }) =>
|
||||
// objects mutability
|
||||
eq(
|
||||
replica(
|
||||
{},
|
||||
Object.freeze({ line: 'Replicants are like any other machine' }),
|
||||
Object.freeze({ author: 'Rich' }),
|
||||
Object.freeze({ author: 'Rich' })
|
||||
),
|
||||
{ line: 'Replicants are like any other machine', author: 'Rich' },
|
||||
),
|
||||
{ line: 'Replicants are like any other machine', author: 'Rich' }
|
||||
)
|
||||
)
|
||||
|
||||
// different value types
|
||||
t(({ eq }) =>
|
||||
// different value types
|
||||
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 }) =>
|
||||
// primitive into an object
|
||||
eq(replica({ a: 4 }, { a: { b: 1 } }).a.b, 1)
|
||||
)
|
||||
|
||||
t(({ eq }) =>
|
||||
// nested array into a primitive
|
||||
eq(
|
||||
replica({ a: { b: { c: [123, 1] } } }, { a: { b: { c: '1' } } }).a.b.c,
|
||||
'1',
|
||||
),
|
||||
'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 } }),
|
||||
// primitive into an array
|
||||
eq(replica({ a: 2 }, { a: [4] }).a, [4])
|
||||
)
|
||||
|
||||
// super nested objects
|
||||
// letter+number indicates the depth
|
||||
t(({ eq }) =>
|
||||
// object into an array
|
||||
eq(replica({ a: { b: [2] } }, { a: [4] }).a, [4])
|
||||
)
|
||||
|
||||
t(({ eq }) =>
|
||||
// array into an object
|
||||
eq(replica({ a: [1, 2, 4] }, { a: { b: [4] } }).a, { b: [4] })
|
||||
)
|
||||
|
||||
t(({ eq }) =>
|
||||
// nested objects
|
||||
eq(replica({ a: { b: 1, c: 2 } }, { a: { c: 23 } }), { a: { b: 1, c: 23 } })
|
||||
)
|
||||
|
||||
t(({ eq }) =>
|
||||
// super nested objects
|
||||
// letter+number indicates the depth
|
||||
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 } } } }
|
||||
),
|
||||
{ a: { b1: { d2: { f3: { i4: 1 }, h3: 1 }, e2: { g3: 2 } }, c1: 2 } },
|
||||
),
|
||||
{ a: { b1: { d2: { f3: { i4: 1 }, h3: 1 }, e2: { g3: 2 } }, c1: 2 } }
|
||||
)
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
|
|
@ -12,50 +12,58 @@ const run = (callback, callLimit, nbr) =>
|
|||
}, 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 }) =>
|
||||
// wait 26ms and execute 4 times every 16ms, executes with a wait time of 26
|
||||
eq(await run(throttle(add, 26), 16, 4), 2)
|
||||
)
|
||||
|
||||
t(async ({ eq }) =>
|
||||
// wait 20ms and execute 2 times every 10ms, executes with a wait time of 26
|
||||
eq(await run(throttle(add, 20), 10, 2), 1)
|
||||
)
|
||||
|
||||
t(async ({ eq }) =>
|
||||
// wait 16ms and execute 5 times every 26ms, will execute with out waiting
|
||||
eq(await run(throttle(add, 16), 26, 5), 4)
|
||||
)
|
||||
|
||||
t(async ({ eq }) =>
|
||||
// it works concurently
|
||||
eq(
|
||||
await Promise.all([
|
||||
run(throttle(add, 16), 26, 5),
|
||||
run(throttle(add, 16), 26, 5),
|
||||
]),
|
||||
[4, 4],
|
||||
),
|
||||
[4, 4]
|
||||
)
|
||||
)
|
||||
|
||||
// tests the trailing option
|
||||
t(async ({ eq }) =>
|
||||
eq(await run(opThrottle(add, 26, { trailing: true }), 16, 4), 1),
|
||||
// tests the trailing option
|
||||
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 in the leading edge of the timeout
|
||||
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 the leading option with wait time not in the leading edge of the timeout
|
||||
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 }) =>
|
||||
// tests without options
|
||||
eq(await run(opThrottle(add, 10), 5, 2), 0)
|
||||
)
|
||||
|
||||
t(async ({ eq }) =>
|
||||
// tests with both options true
|
||||
eq(
|
||||
await run(opThrottle(add, 26, { trailing: true, leading: true }), 16, 4),
|
||||
2,
|
||||
),
|
||||
2
|
||||
)
|
||||
)
|
||||
|
||||
Object.freeze(tests)
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
### Instructions
|
||||
|
||||
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
|
||||
|
||||
- [lodash.com/docs/4.17.15#debounce](https://lodash.com/docs/4.17.15#debounce)
|
||||
|
|
Loading…
Reference in New Issue