Skip to content

dorminhoco test + resolution #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

nato-re
Copy link
Collaborator

@nato-re nato-re commented Dec 4, 2020

Adiciona exercício junto a gabarito, com intensão de avaliação para construir enunciado

Issue: #11

@nato-re nato-re requested a review from frattezi December 4, 2020 01:02
@nato-re nato-re self-assigned this Dec 4, 2020
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Muito obrigado pela contribuição! Traga mais!

@nato-re nato-re added this to the V1 milestone Dec 4, 2020
expect(typeof sonho).toBe('string');
});

it(`resultado deve ser uma string`, async () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

acho que aqui deveria ser outra mensagem

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mara, segue no comitão bomba anexado no email <3

@frattezi
Copy link
Collaborator

frattezi commented Dec 5, 2020

Vamos pensar em como deixar este exercise apenas no template inicial + Uma historinha legal. Vendo o código eu pensei que poderiamos ter uma lista fixa que o user não pode alterar a forma e deve printar cada item em ordem, porém, exigimos uma ordem de impressão diferente da ordem da lista? Não sei ainda não consigo ver esse danado como exercício.

Copy link
Collaborator

@frattezi frattezi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boa! Vamos conversando e vendo como melhorar

'Mozão'
]
const randomPosition = Math.floor(Math.random() * dreams.length)
const randomDream = (resolve) => () => resolve(dreams[randomPosition])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sempre tentar manter um pattern, se aqui as consts estão em inglês isto deveria ser seguido em todo code, para um lado ou pro outro

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mara <3

expect(setTimeout).toBeCalledWith(expect.any(Function), 2000)


expect(setTimeout).toBeCalledWith(expect.any(Function), 42);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

função chamada com undefined, não entendi o processo

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seu teste não é async, acredito que isto está impactando sua leitura

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

faz mt sentido :D
vou implementar!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@@ -1,24 +1,21 @@
const dreams = [
const dreamList = [
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ainda estou pensando em como fazer com a lista sem aleatoriaedade

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

acho que fica mais fácil. talvez, vamos tentar moldar a ordem do problema de uma vez antes de ir para implementação

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aleatoriedade é o que torna os testes mais fracos, dado que você pode ter resultados diferentes para cada vez que vc rodar os testes, acho que seria bom simplificar essa implementação mesmo

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uma possibilidade é mockar a função 'Math.random()'

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

muito bem, vou implementar, junto com os testes dos caminhos feios aushda <3

@@ -1,24 +1,21 @@
const dreams = [
const dreamList = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uma possibilidade é mockar a função 'Math.random()'

const sleep = (ms, cb) => setTimeout(cb, ms);

const dorminhoco = async (milliseconds, dreamList) => {
const promisedDream = new Promise((resolve) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A gente não precisa disso.

vc ta misturando callback com async/await, sendo que ambos server ao mesmo proposito, fazer uma chamada no asincrona.

recomendo:

  1. remover o cb do sleep
  2. chamar a função randomDream depois de um await

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fiz no commit, acho que ficou de acordo com suas colocações

Comment on lines 11 to 17
const sleep = (ms, cb) => setTimeout(cb, ms);

const dorminhoco = async (milliseconds, dreamList) => {
const promisedDream = new Promise((resolve) =>
sleep(milliseconds, randomDream(dreamList, resolve))
);
const dream = await promisedDream;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const sleep = (ms, cb) => setTimeout(cb, ms);
const dorminhoco = async (milliseconds, dreamList) => {
const promisedDream = new Promise((resolve) =>
sleep(milliseconds, randomDream(dreamList, resolve))
);
const dream = await promisedDream;
const sleep = (ms) => new Promise(res => setTimeout(cb, res);
export const dorminhoco = async (milliseconds, dreamList) => {
await sleep(milliseconds)
const dream = randomDream()

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gostei, implementei parecido no commit

@@ -0,0 +1,26 @@
const main = require('./main');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vamos evitar require em nossos projetos em pro da sintaxe mais recente e recomendada de import { dorminhoco } from './main'

return dream;
};

module.exports = { dorminhoco };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vamos evitar esse export

jest.clearAllMocks();
jest.useFakeTimers();
});
const dreamMock = ['não lembro do sonho'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declare essa variavel fora do describe, por padrão, geralmente declaramos constantes imutáveis no escopo raiz como uma boa prática


expect(setTimeout).toBeCalledWith(expect.any(Function), 42);
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Não temos casos de testes com listas vazias.

quando fazemos unit teste temos que validar caminhos felizes e caminhos tristes, como por exemplo:

  • lista vazia
  • string no lugar da lista
  • lista undefined
  • so on

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acho válido, mas estou tentando testar com o node assim:
dorminhoco(42, [])
e dá isso:
SyntaxError: Unexpected token 'export'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node por padrão não reconhece o exoprt, precisamos do babel para tal. No entanto, o Jest deveria lidar com isso pra gente.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O ideal é rodar com jest e ir testando

expect(setTimeout).toBeCalledWith(expect.any(Function), 2000)


expect(setTimeout).toBeCalledWith(expect.any(Function), 42);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

it(`setTimeout dever ser sido chamado uma vez`, async () => {
main.dorminhoco(42, dreamMock);

expect(setTimeout).toBeCalledTimes(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

não estamos validando a função setTimeout, ela já é testada pelo core team do JS.

O que queremos testar é a função dorminhoco e seus retornos

});
const dreamMock = ['não lembro do sonho'];

it(`resultado deve ser uma string`, async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Este caso de teste é um bom exemplo de caminho feliz, agora precisamos fazer os testes para caminhos triste

Copy link
Contributor

@marco-souza marco-souza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bom trabalho, a função já ta bem melhor! 👍

Alguns pontos de atenção:

  • não devemos enviar a resolução do exercicio, apenas os testes, a descrição e algumas funções uteis para resolver o problema
  • Os nomes dos testes precisam ser mais descritivos, pois é onde os estudantes da podcodar vão validar suas resoluções.
  • Precisamos de um padrão de nome para todos os casos de teste para facilitar a leitura de quem for resolver
  • Temos de prestar atenção nos asserts, para garantirmos que estamos validando o que queremos de fato, e não fazendo validacões que envolvem transformação/coerção de tipos, e funções nativas do JS.

PS: foi mal os longos reviews, não é nada pessoal, hahaha, só estou tentando manter o exercicio dentro dos nossos padrões (que ainda precisam ser melhor definidos, mas já conseguimos dar dicas de boas práticas e tals...) 😃


expect(setTimeout).toBeCalledWith(expect.any(Function), 42);
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node por padrão não reconhece o exoprt, precisamos do babel para tal. No entanto, o Jest deveria lidar com isso pra gente.

expect(setTimeout).toBeCalledWith(expect.any(Function), 42);
});

it(`checa se sonho tem retorno válido`, async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acho que os nomes dos casos de testes precisam ser mais descritivos como "Quando a lista de sonhos é vazia, o retorno deve ser inválido" ou algo assim

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isso ainda não foi implementado, mas já está em mente


expect(setTimeout).toBeCalledWith(expect.any(Function), 42);
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O ideal é rodar com jest e ir testando

Copy link
Contributor

@marco-souza marco-souza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boa, estamos chegando lá! 🐱

Próximos passos ao meu ver seriam

  • sugestões da revisão atual
  • remover resolução da main.js
  • Adicionar descrição do problema no README.md
  • rodar prettier e/ou eslint para mantar os estilos homogêneos
  • melhor descrição dos testes
  • Refatorar os commits com git rebase -i para entrar no padrão definido pelo @frattezi

jest.clearAllMocks();
jest.useFakeTimers();
jest.restoreAllMocks();
jest.spyOn(global.Math, 'random').mockReturnValue(0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boa, mandou bem no mock!

Uma dúvida: precisamos de dar spyOn sempre antes de cada test case? Ou podemos usá-lo apenas uma vez e aceitar que o jest.clearAllMocks() vai limpar o mock pra gente?

});

it(`resultado deve ser uma string`, () => {
return dorminhoco(42, dreamMock).then((dream) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acho que seria mais elegante usar async/await para lidar com promises


it(`resultado deve ser uma string`, () => {
return dorminhoco(42, dreamMock).then((dream) => {
expect(typeof dream).toBe('string');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Não precisamos validar o type, dado que estamos validando o valor + tipo logo abaixo

});

it(`checa retorno com entrada como string`, () => {
return dorminhoco(42, 'nao sou um array').then((dream) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

me parece estranho rodar com uma string. Não deveriamos rodar apenas com array? Mesmo o JS tratando Array como String, acho que seria melhor nao rodar para strings

# input:
42 "minha string'

# output
undefined


it(`espera que setTimeout seja chamado com uma função`, async () => {
jest.useFakeTimers();
dorminhoco(42, dreamMock);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dado que o dominhoco é uma promise, precisamos de dar await aqui para aguardar a execução. Do jeito que está vai passar por causa do asset feito abaixo, que só valida se setTimeout foi chamado, mas num teste real, precisamos aguardar as promisses se resolverem antes de validar o retorno

Comment on lines +14 to +18

await sleep(milliseconds)

const dream = randomDream(dreamList);
return dream;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
await sleep(milliseconds)
const dream = randomDream(dreamList);
return dream;
if (Array.isArray(dreamList))
return // early return to avoid extra processing
await sleep(milliseconds)
return randomDream(dreamList)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplificando a implementação

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants