Browse Source

moving js test comments for students

pull/641/head
lee 4 years ago committed by Clément
parent
commit
498fdd9897
  1. 32
      js/tests/all_test.js
  2. 31
      js/tests/debounce_test.js
  3. 56
      js/tests/deep-copy_test.js
  4. 2
      js/tests/dr-strange_test.js
  5. 6
      js/tests/for-each_test.js
  6. 48
      js/tests/fusion_test.js
  7. 22
      js/tests/get-json_test.js
  8. 16
      js/tests/gougle-search_test.js
  9. 24
      js/tests/interpolation_test.js
  10. 14
      js/tests/invert_test.js
  11. 40
      js/tests/is-winner_test.js
  12. 33
      js/tests/neuron_test.js
  13. 28
      js/tests/pronoun_test.js
  14. 40
      js/tests/race_test.js
  15. 56
      js/tests/replica_test.js
  16. 48
      js/tests/throttle_test.js
  17. 2
      subjects/debounce/README.md

32
js/tests/all_test.js

@ -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({}), {}))
t(async ({ eq }) =>
// it should work with an empty object
eq(await all({}), {})
)
// it should work with synchronous values
t(async ({ eq }) => eq(await all({ a: 1, b: true }), { a: 1, b: true }))
t(async ({ eq }) =>
// it should work with synchronous values
eq(await all({ a: 1, b: true }), { a: 1, b: true })
)
// it should work with pending promises
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)

31
js/tests/debounce_test.js

@ -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]
)
)
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)
)
// 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 }) =>
// 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)

56
js/tests/deep-copy_test.js

@ -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 })
)
t(({ eq }) =>
// simple array
copyAndCompare(eq, [1, 'a'])
)
t(({ eq }) =>
// works with any value type
copyAndCompare(eq, [console.log, /hello/])
)
t(({ eq }) =>
// nesting object
copyAndCompare(eq, { a: { b: { c: 1 } } })
)
t(({ eq }) =>
// nesting array
copyAndCompare(eq, [1, [2, [true]]])
)
t(({ eq }) =>
// mixed nesting
copyAndCompare(eq, [{ a: () => {} }, ['b', { b: [3] }]])
)
t(({ eq }) =>
// undefined value
copyAndCompare(eq, { undef: undefined })
)
// 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 }) => {
// 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)

2
js/tests/dr-strange_test.js

@ -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'),

6
js/tests/for-each_test.js

@ -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))

48
js/tests/fusion_test.js

@ -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'))
t(({ eq }) =>
// simple string
eq(fusion({ str: 'hello' }, { str: 'there' }).str, 'hello there')
)
// handle empty strings
t(({ eq }) => eq(fusion({ str: 'hello' }, { str: '' }).str, 'hello '))
t(({ eq }) =>
// handle empty strings
eq(fusion({ str: 'hello' }, { str: '' }).str, 'hello ')
)
// multiple strings
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]))
t(({ eq }) =>
// simple arrays
eq(fusion({ arr: [1, '2'] }, { arr: [2] }).arr, [1, '2', 2])
)
// multiple arrays
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

22
js/tests/get-json_test.js

@ -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
)
})

16
js/tests/gougle-search_test.js

@ -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)
)),
})

24
js/tests/interpolation_test.js

@ -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)

14
js/tests/invert_test.js

@ -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)

40
js/tests/is-winner_test.js

@ -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'))
t(async ({ eq }) =>
// testing no country
eq(await isWinner(''), ' never was a winner')
)
// testing correct number of times but wrong continent
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)

33
js/tests/neuron_test.js

@ -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)

28
js/tests/pronoun_test.js

@ -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)

40
js/tests/race_test.js

@ -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), []))
t(async ({ eq }) =>
// empty array returns an empty array
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), []))
t(async ({ eq }) =>
// a count of less than 1 also returns an empty array
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]),
// 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 !")

56
js/tests/replica_test.js

@ -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))
t(({ eq }) =>
// primitive into an object
eq(replica({ a: 4 }, { a: { b: 1 } }).a.b, 1)
)
// nested array into a primitive
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]))
t(({ eq }) =>
// primitive into an array
eq(replica({ a: 2 }, { a: [4] }).a, [4])
)
// object into an array
t(({ eq }) => eq(replica({ a: { b: [2] } }, { a: [4] }).a, [4]))
t(({ eq }) =>
// object into an array
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] }))
t(({ eq }) =>
// array into an object
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 } }),
// nested objects
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 }) =>
// 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)

48
js/tests/throttle_test.js

@ -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))
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)
)
// 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))
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)
)
// 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))
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)
)
// it works concurently
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))
t(async ({ eq }) =>
// tests without options
eq(await run(opThrottle(add, 10), 5, 2), 0)
)
// tests with both options true
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)

2
subjects/debounce/README.md

@ -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…
Cancel
Save