Exercício:
A função "a" deve retornar uma promise sem usar a classe Promise.
Modifique a função "b" de forma que execute a promise de "a" sem usar then/catch.
function a() {
return new Promise(function (resolve, reject) {
resolve('ok');
});
}
function b() {
a().then(function(res) {
console.log(res);
}).catch(function(err) {
console.log(err);
})
}
describe("Solution", function() {
it("should test for something", function() {
// Test.assertEquals(1 + 1, 2);
// assert.strictEqual(1 + 1, 2);
});
});
Exercício:
Reescreva os códigos utilizando os novos recursos do ES6
// 1 - Encontre um número maior que 6
var arr = [1, 4, 6, 8, 10];
var resp = null;
for (var i = 0; i < arr.length; ++i) {
if (arr[i] > 6) {
resp = arr[i];
break;
}
}
// 2 - Encontre o índice de um número maior que 6
var arr = [1, 4, 6, 8, 10];
var resp = null;
for (var i = 0; i < arr.length; ++i) {
if (arr[i] > 6) {
resp = i;
break;
}
}
// 3 - Encontre os numeros maiores que 6
var arr = [1, 4, 6, 8, 10];
var resp = arr.reduce((carry, item) => {
if (item > 6)
carry.push(item);
return carry;
}, []);
// 4 - O array contém o número 6?
var arr = [1, 4, 6, 8, 10];
var resp = arr.indexOf(6) > -1;
// 5 - Todos os números do array são números pares?
var arr = [2, 4, 6, 8, 9];
var resp = true;
for (var i = 0; i < arr.length; ++i) {
if (arr[i] % 2 !== 0) {
resp = false;
break;
}
}
// 6 - Algum número no array é impar?
var arr = [2, 4, 0, -2];
var resp = arr.reduce(function (carry, item) {
return carry || (item % 2 !== 0);
}, false);
describe("Solution", function() {
it("should test for something", function() {
Test.assertEquals(1 + 1, 2);
});
});
Exercício:
Crie um construtor para classe Collection onde receba 2 parâmetros. Não esqueça de iniciar o construtor da classe base.
new Collection('#body', true);
class Component {
constructor(dom) {
console.log('Parent class constructor executed!');
this.dom = dom;
}
onCreate() {
return true;
}
}
class Collection {
//
}
describe("Solution", function(){
it("should test for something", function(){
Test.assertEquals(new Collection('#body', true).onCreate(), true, "This is just an example of how you can write your own TDD tests");
});
});
Exercício:
Crie a classe Title, herde Component e sobrescreva o método onCreate para retornar a string "super!", mas que também execute o método onCreate da classe base.
class Component {
constructor(dom) {
this.dom = dom;
}
onCreate() {
console.log('onCreate from parent class');
return 'missing';
}
static on(event, callback) {
callback();
}
async emit(event, data) {}
}
describe("Solution", function(){
it("should test for something", function(){
Test.assertEquals(new Title().onCreate(), "super!", "This is just an example of how you can write your own TDD tests");
});
});
Exercício:
Use os novos recursos do ES6 para resolver os problemas do dia a dia.
// 1 - Criar um separador de 20 hífens
var separador = '';
for (var i = 20; i--;)
separador += '-';
// 2 - Completar com espaços à esquerda para formar uma string de 20 caracteres
var titulo = 'UOL';
titulo = new Array(20 - titulo.length + 1).fill('').join(' ') + titulo;
// 3 - Completar com espaços à direita para formar uma string de 20 caracteres
var titulo = 'UOL';
for (var i = 20 - titulo.length; i--; titulo += ' ');
// 4 - Verificar se a string contém outra string em boolean
var titulo = 'UOL - O melhor conteúdo';
var resp = titulo.indexOf('melhor') !== -1;
// 5 - Verificar se a string começa com outra string em boolean
var titulo = 'UOL - O melhor conteúdo';
var resp = titulo.indexOf('UOL') == 0;
// 6 - Verificar se a string termina com outra string em boolean
var titulo = 'UOL - O melhor conteúdo';
var resp = new RegExp('melhor$').test(titulo);
describe("Solution", function(){
it("should test for something", function(){
Test.assertEquals(1, 1, "This is just an example of how you can write your own TDD tests");
});
});
Com destructuring e deep matching conseguimos navegar por um objeto até chegar no valor da propriedade.
Exercício:
Navague até o título nos array resultados e imprima no console o valor. Assuma "Brasil" como valor padrão quando "titulo" não existir.
let results = [
{materia: {conteudo: {titulo: 'São Paulo'}}, tags: [1, 2, 3]},
{materia: {conteudo: {}}, tags: [3, 2]},
{materia: {conteudo: {titulo: 'Rio de Janeiro'}}, tags: [3, 2]},
];
for (const result of results) {
let titulo = result.materia.conteudo.titulo || 'Brasil';
console.log(titulo);
}
describe("Solution", function(){
it("should test for something", function(){
Test.assertEquals(1, 1, "This is just an example of how you can write your own TDD tests");
});
});
Exercício:
Troque os valores de A por B e B por A sem criar uma nova variável.
let a = 5, b = 10;
// reescreva
// resolva sem precisar de uma nova variável
let c = a;
a = b;
b = c;
describe("Solution", function(){
it("should test for something", function(){
Test.assertEquals(a == 10 && b == 5, true, "This is just an example of how you can write your own TDD tests");
});
});
Quando estamos criando uma lib em JS é comum colocarmos tudo dentro de uma função anônima. Mas porquê? Um dos motivos é garantir que as variáveis externas não vão conflitar com suas variáveis e que as variáveis que você está criando não vão conflitar com o resto do programa. Existem outros motivos, mas voltando a raiz esse é o principal.
Exercício:
ES6 trouxe um novo recurso que veio para substituir funções anônimas quando queremos criar um escopo/contexto. Substitua a função anônima por esse recurso.
function todo() {
return 'Walk';
}
// reescrever em ES6
(function() {
function todo() {
return 'Run';
}
})();
describe("Solution", function(){
it("should test for something", function(){
Test.assertEquals(todo(), 'Walk', "This is just an example of how you can write your own TDD tests");
});
});
Para definir variáveis no JS, opcionalmente, mas altamente recomendado usamos a keyword var. Var possui algumas particularidades, como içamento, que a princípio veio para otimizar nosso código mas causou alguns efeitos colaterais.
ES6 trouxe duas novas palavras-chaves para auxiliar na declaração de variáveis: let e const.
Exercício:
Substitua var por let ou const quando necessário.
// Exercício 1
var titulo = "UOL - O melhor conteúdo";
// Exercício 2
var tags = []
tags.push(...['A', 'B']);
// Exercício 3
var descricao = "Em 1999";
descricao += " em São Paulo";
// Exercício 4
var materia = {titulo: "Barão de Limeira"};
materia.titulo = "Alameda " + materia.titulo;
// Exercício 5
for (var i = 10; i--;) {
console.log(i);
}
// Exercício 6
for (var tag of ['A', 'B']) {
console.log(tag);
}
// Exercício 7
for (var j = [].length; j--;) {}
if (j === -1) {
console.log('Não encontrei');
}
// Exercício 8
var a = 123;
{
a *= 2;
}
console.log(a);
// Exercício 9
var state = 'active';
function stop() {
state = 'paused';
}
stop();
// Exercício 10
var TRUE = !0;
describe("Solution", function(){
it("should test for something", function(){
Test.assertEquals(true, true, "This is just an example of how you can write your own TDD tests");
});
});
Exercício:
Capture o reject da Promise em ES6.
function monteCarlo() {
return new Promise(function (resolve, reject) {
reject({server: 'down'});
});
}
async function main() {
// converter para ES6
const results = await monteCarlo();
return true;
}
describe("Solution", function(){
it("should test for something", async function(){
Test.assertEquals(await main(), true, "This is just an example of how you can write your own TDD tests");
});
});
Não há limite para a quantidade de parâmetros que você pode enviar para uma função JS. A assinatura é um meio mais fácil de acessar alguns desses parâmetros. Em alguns casos pode ser muito útil definir assumir um valor padrão quando o parâmetro é opcional. Uma forma de verificar se o parâmetro foi ou não definido é validar com undefined. Só que com ES6 existe uma forma mais simples e elegante de tornar parâmetros opcionais.
Exercício:
Reescreva o código em ES6.
// reescreva em ES6
function main(a, b, c) {
if (typeof b == 'undefined')
b = 2;
if (typeof c == 'undefined')
c = 3
return a * b * c;
}
describe("Solution", function(){
it("validating", function(){
Test.assertEquals(main(1), 6, "b e c opcionais");
Test.assertEquals(main(2, 3), 18, "c opcional");
Test.assertEquals(main(2, 2, 2), 8, "todos parâmetros");
});
});
Além de trazer novidades na escrita da linguagem, ES6 também trouxe novas classes.
Exercício:
Remover os itens duplicados do array sem percorrer o array
const main = () => {
let links = [
'https://www.uol',
'https://www.bol.com.br',
'https://www.uol',
'https://noticias.uol.com.br',
'https://www.bol.com.br',
];
// converter para ES6
var uniqueLinks = links.reduce(function (carry, item) {
if (carry.indexOf(item) === -1) {
carry.push(item);
}
return carry;
}, []);
return uniqueLinks.length;
};
Async / await vieram para facilitar a execução de código assíncrono, muitas vezes encapsulado em Promises e dar maior controle sobre o fluxo de execução, dando a possibilidade de transformar trechos assíncronos em síncronos evitando callbacks excessivos (callback from hell).
Exercício:
Converta a execução da Promise para async/await.
function monteCarlo() {
return new Promise(function (resolve, reject) {
resolve([{
titulo: 'UOL - O Melhor conteúdo'
}]);
});
}
async function main() {
// converter para ES6
monteCarlo().then(function(response) {
console.log(response)
});
return true;
}
describe("Solution", function(){
it("should test for something", async function(){
Test.assertEquals(await main(), true, "This is just an example of how you can write your own TDD tests");
});
});
LazyRange cria um range de um número até outro com generators. O benefício do generator é que o range só será criado quando necessário.
E se pudermos alinhar generators de forma que várias instruções sejam executadas porém somente quando necessário, evitando percorrer o mesmo array diversas vezes?
Estamos falando de pura performance.
Exercício:
Implementar a função plusOne que some 1 em cada item de doubleRangeValue e retorne os valores sob demanda (generator).
function* lazyRange(start, stop) {
while (start <= stop) {
console.log(`Interando ${start}`);
yield start;
++start;
}
}
function* doubleRangeValue(...args) {
for (let value of lazyRange(...args)) {
value *= 2;
console.log(`Dobro ${value}`);
yield value;
}
}
function* plusOne() {
// implemente
}
async function main() {
let resp = [...plusOne(1, 5)];
return resp.join(',');
}
describe("Solution", function(){
it("should test for something", async function(){
Test.assertEquals(await main(), "3,5,7,9,11", "Victory");
});
});
"Você precisa disso para agora?"
Ou então apenas repasse.
Generator é uma instrução que fica na espera, somente é executada quando necessário.
Exercício:
Percorrer o generator na função main e para cada item imprimir no console seu valor.
function* lazyRange(start, stop) {
while (start <= stop) {
console.log(`Interando ${start}`);
yield start;
++start;
}
}
function createRange() {
console.log("Criando um range");
return lazyRange(1, 10);
}
function getData() {
let theRange = createRange();
console.log("Repassando o range");
return {theRange};
}
function main() {
let resp = getData();
// percorra o generator executando o trecho comentado abaixo
// console.log(`Valor ${item}`);
return 1;
}
describe("Solution", function(){
it("should test for something", function(){
Test.assertEquals(main(), 1, "This is just an example of how you can write your own TDD tests");
});
});