Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 67 additions & 72 deletions src/www/js/es-syntax/syntax.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ describe('ES2015 syntax', () => {
* Assume the codebase uses `let` declarations only for variables
* that are reassigned. Use `const` otherwise.
*/
var a = 4
var b = [1, 2, 3]
let a = 4
const b = [1, 2, 3]

if (b.length < 4) b.push(a)
expect(b).toEqual([1, 2, 3, 4])

var a = 2
var c = [1, a, 3]
a = 2
const c = [1, a, 3]
expect(c).toEqual([1, 2, 3])
})
})

describe('loops', () => {
it('rewrite the for loop to use a let variable', () => {
const nums = []
for (var i = 0; i < 3; i++) {
for (let i = 0; i < 3; i++) {
nums.push(i)
}
expect(nums).toEqual([0, 1, 2])
Expand All @@ -31,44 +31,37 @@ describe('ES2015 syntax', () => {
it('rewrite using object function shorthand', () => {
const person = {
name: 'Andrew',
getName: function() { return this.name }
getName() {return this.name}
}
expect(person.getName()).toEqual('Andrew')
})

it('rewrite using object property shorthand', () => {
const name = 'Andrew'
const person = { name: name }
const person = { name }
expect(person.name).toEqual('Andrew')
})
})

describe('functions', () => {
it('rewrite the function declaration with arrow syntax', () => {
const foo = () => 'foo'
expect(foo()).toEqual('foo')

function foo() {
return 'foo'
}
})

it('rewrite the function declaration, and use implicit return for anonymous function', () => {
expect(addOneToValues([1, 2, 3])).toEqual([2, 3, 4])
expect(() => addOneToValues([])).toThrow('Values required')

function addOneToValues(xs) {
if (xs.length < 1) throw new Error('Values required')
// HINT: you can use an implicit return arrow function by omitting the curly brackets
return xs.map(function (x) {
return x + 1
})
return xs.map(x => x + 1)
}
expect(addOneToValues([1, 2, 3])).toEqual([2, 3, 4])
expect(() => addOneToValues([])).toThrow('Values required')
})

it('rewrite the logic in the function to use default parameters', () => {
const getIndexOfFoo = (str) => {
const strDefault = str || ''
return strDefault.indexOf('foo')
const getIndexOfFoo = (str = '') => {
return str.indexOf('foo')
}

expect(getIndexOfFoo('hello foo bar')).toEqual(6)
Expand All @@ -79,32 +72,20 @@ describe('ES2015 syntax', () => {
describe('array spread and destructuring', () => {
it('rewrite using array destructuring', () => {
const favoriteThings = ['tea', 'chocolate', 'bicycles', 'mangoes']
const tea = favoriteThings[0]
const chocolate = favoriteThings[1]
const others = favoriteThings.slice(2)
const [tea, chocolate, ...others] = favoriteThings
expect(tea).toEqual('tea')
expect(chocolate).toEqual('chocolate')
expect(others).toEqual(['bicycles', 'mangoes'])
})

it('rewrite to use rest parameters', () => {
// takes the first number, and then adds it to each value in the remaining numbers and returns an array
const addNToNumbers = function () {
const n = arguments[0]
const nums = Array.prototype.slice.call(arguments, 1)
return nums.map(val => val + n)
}
const addNToNumbers = (first, ...rest) => rest.map(num => num + first)
expect(addNToNumbers(3, 1, 2, 5)).toEqual([4, 5, 8])
})

it('rewrite using spread syntax to shallow-copy an array', () => {
const copyArray = (arr) => {
const copy = []
for (let i = 0; i < arr.length; i++) {
copy.push(arr[i])
}
return copy
}
const copyArray = (arr) => [...arr]

const arr1 = [1, 2, 3]
const copy = copyArray(arr1)
Expand All @@ -114,56 +95,63 @@ describe('ES2015 syntax', () => {
})

it('write a function that immutably adds a new item to an array', () => {
const concat = (arr, item) => {
arr.push(item)
return arr
}
// const concat = (arr, item) => {
// arr.push(item)
// return arr
// }
const concat = (arr, item) => [...arr, item]
const animals = ['cat', 'dog', 'bird']
const moarAnimals = concat(animals, 'alpaca')
expect(animals === moarAnimals).toEqual(false)
expect(moarAnimals).toEqual(['cat', 'dog', 'bird', 'alpaca'])
})

it('write a function that immutably prepends a new item to an array', () => {
const prepend = (arr, item) => {
arr.unshift(item)
return arr
}
// const prepend = (arr, item) => {
// arr.unshift(item)
// return arr
// }
const prepend = (arr, item) => [item, ...arr]
const animals = ['cat', 'dog', 'bird']
const moarAnimals = prepend(animals, 'alpaca')
expect(moarAnimals).toEqual(['alpaca', 'cat', 'dog', 'bird'])
expect(animals === moarAnimals).toEqual(false)
})

it('rewrite using spread syntax to duplicate the contents of an array', () => {
const duplicateArrayContents = (arr) => {
const result = []
for (let i = 0; i < 2; i++) {
for (let j = 0; j < arr.length; j++) {
result.push(arr[j])
}
}
return result
}
// const duplicateArrayContents = (arr) => {
// const result = []
// for (let i = 0; i < 2; i++) {
// for (let j = 0; j < arr.length; j++) {
// result.push(arr[j])
// }
// }
// return result
// }
const duplicateArrayContents = (arr) => [...arr, ...arr]

expect(duplicateArrayContents([1, 2, 3])).toEqual([1, 2, 3, 1, 2, 3])
})

it('CHALLENGE: rewrite using spread syntax to duplicate and reverse contents of an array', () => {
// HINT: You can immutably reverse an array with: `[...array].reverse()`
const duplicateAndReverseArrayContents = (arr) => {
const result = []
for (let i = 0; i < 2; i++) {
for (let j = 0; j < arr.length; j++) {
if (i === 0) {
result.push(arr[j])
} else {
result.push(arr[arr.length - 1 - j])
}
}
}
return result
}
// const duplicateAndReverseArrayContents = (arr) => {
// const result = []
// for (let i = 0; i < 2; i++) {
// for (let j = 0; j < arr.length; j++) {
// if (i === 0) {
// result.push(arr[j])
// } else {
// result.push(arr[arr.length - 1 - j])
// }
// }
// }
// return result
// }

const duplicateAndReverseArrayContents = (arr) => [...arr, ...[...arr].reverse()]
// WRONG: this will reverse the original arr!
//const duplicateAndReverseArrayContents = (arr) => [...arr, arr.reverse()]

expect(duplicateAndReverseArrayContents([1, 2, 3])).toEqual([1, 2, 3, 3, 2, 1])
})
Expand All @@ -174,23 +162,30 @@ describe('ES2018 syntax', () => {
describe('object spread and destructuring', () => {
it('rewrite using object destructuring', () => {
const person = { id: 42, name: 'Andrew', location: 'Seattle' }
const id = person.id
const name = person.name
const location = person.location
// const id = person.id
// const name = person.name
// const location = person.location

// WRONG: [id, name, location] = {person}
const {id, name, location} = person
expect(id).toEqual(42)
expect(name).toEqual('Andrew')
expect(location).toEqual('Seattle')
})

it('rewrite using object spread and destructuring', () => {
// TODO
const withoutKey = (keyToRemove, obj) => {
const copy = {}
for (const [key, value] of Object.entries(obj)) {
if (key !== keyToRemove) copy[key] = value
}
// const copy = {}
// for (const [key, value] of Object.entries(obj)) {
// if (key !== keyToRemove) copy[key] = value
// }
const copy = {...obj}
delete copy[keyToRemove]
return copy
}


const person = { id: 42, name: 'Andrew', location: 'Seattle' }
expect(withoutKey('id', person)).toEqual({ name: 'Andrew', location: 'Seattle' })
expect(withoutKey('location', person)).toEqual({ id: 42, name: 'Andrew' })
Expand Down
90 changes: 63 additions & 27 deletions src/www/js/functional/array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ describe('Array higher-order functions', () => {
it('rewrite the for loop with forEach', () => {
const mockFn = jest.fn()

// TODO rewrite with #forEach
// Remember: forEach provides three args: element, index, array
for (let i = 0; i < users.length; i++) {
mockFn(users[i])
}
// for (let i = 0; i < users.length; i++) {
// mockFn(users[i])
// }
users.forEach(mockFn)

expect(mockFn.mock.calls.length).toEqual(3)
expect(mockFn.mock.calls).toEqual([
Expand All @@ -26,44 +25,81 @@ describe('Array higher-order functions', () => {

describe('#filter', () => {
it('rewrite the filter operation without a for loop', () => {
const usersWithFavoriteColorBlue = []
// const usersWithFavoriteColorBlue = []

for (let i = 0; i < users.length; i++) {
const user = users[i]
if (user.favoriteColor === 'blue') {
usersWithFavoriteColorBlue.push(user)
}
}
// for (let i = 0; i < users.length; i++) {
// const user = users[i]
// if (user.favoriteColor === 'blue') {
// usersWithFavoriteColorBlue.push(user)
// }
// }
const usersWithFavoriteColorBlue = users.filter(user => user.favoriteColor === 'blue')

expect(usersWithFavoriteColorBlue).toEqual([users[0]])
})

it('EXTRA CREDIT: write a function #reject that does the opposite of #filter and uses that method', () => {
it('write a function #reject that does the opposite of #filter and uses that method', () => {
// const reject = (pred, array) => {
// const result = []
// for (let i = 0; i < array.length; i++) {
// if (!pred(array[i])) {
// result.push(array[i])
// }
// }

const reject = (pred, array) => {
const result = []
for (let i = 0; i < array.length; i++) {
if (!pred(array[i])) {
result.push(array[i])
}
}
let result = array.filter(elem => !pred(elem))
return result
}

const usersWithoutFavoriteColorblue = reject(user => user.favoriteColor === 'blue', users)
expect(usersWithoutFavoriteColorblue).toEqual([users[1], users[2]])
})
})

describe('#map', () => {
it('rewrite using #map', () => {
const incrementAgeOfHumans = (humans) => {
const result = []
for (let i = 0; i < humans.length; i++) {
result.push({ ...humans[i], age: humans[i].age + 1 })
}
describe('#every', () => {
it('implement the #every method', () => {
// === Uncomment me and implement ===
Array.prototype.every = function(pred) {
// console.log(this) // access the array with `this`
let result = true
this.forEach(elem => {
if(!pred(elem)) result = false
})
return result
}
expect([1, 2, 3].every(x => x > 0)).toEqual(true)
expect([1, 2, 3].every(x => x > 2)).toEqual(false)
})
})

describe('#some', () => {
it('implement the #some method', () => {
// === Uncomment me and implement ===
Array.prototype.some = function(pred) {
// console.log(this) // access the array with `this`
let result = false
this.forEach(elem => {
if(pred(elem)) result = true
})
return result
}
expect([1, 2, 3].some(x => x > 2)).toEqual(true)
expect([1, 2, 3].some(x => x > 4)).toEqual(false)
})
})

describe('#map', () => {
it('rewrite using #map', () => {
// const incrementAgeOfHumans = (humans) => {
// const result = []
// for (let i = 0; i < humans.length; i++) {
// result.push({ ...humans[i], age: humans[i].age + 1 })
// }
// return result
// }

// TODO
const incrementAgeOfHumans = (humans) => humans.map(human => human.age + 1)
expect(incrementAgeOfHumans(users)).toEqual([
{ id: 1, name: 'Andrew', age: 34, favoriteColor: 'blue' },
{ id: 2, name: 'Billy', age: 21, favoriteColor: 'red' },
Expand Down
Loading