Reputation: 79
I followed Dev Eds course on creating a todo list, but now I want to write some tests to test the code. I want to use Jest but I'm not sure how to write a test to make sure that a todo is created, and deleted.
I've added the app.js file below (there is are html/css files as well). My attempt at writing a test is under the app.js file.
//Selectors
const todoInput = document.querySelector('.todo-input');
const todoButton = document.querySelector('.todo-button');
const todoList = document.querySelector('.todo-list');
const filterOption = document.querySelector('.filter-todo');
//Event Listeners
todoButton.addEventListener('click', addTodo);
todoList.addEventListener('click', deleteCheck);
filterOption.addEventListener('change', filterTodo);
//Functions
function addTodo(event){
//console.log(event.target);
// prevent form from submitting
event.preventDefault();
const todoDiv = document.createElement("div");
todoDiv.classList.add("todo");
//create LI
const newTodo = document.createElement('li');
newTodo.innerText = todoInput.value;
newTodo.classList.add('todo-item');
todoDiv.appendChild(newTodo);
// Checkmark button
const completedButton = document.createElement('button');
completedButton.innerHTML = '<i class="fas fa-check"></i>'
completedButton.classList.add("complete-btn");
todoDiv.appendChild(completedButton);
// Delete button
const deleteButton = document.createElement('button');
deleteButton.innerHTML = '<i class="fas fa-trash"></i>'
deleteButton.classList.add("delete-btn");
todoDiv.appendChild(deleteButton);
// Append to list
todoList.appendChild(todoDiv);
// clear todo input value
todoInput.value = "";
}
function deleteCheck(e){
//console.log(e.target);
const item = e.target;
if(item.classList[0] === 'delete-btn'){
const todo = item.parentElement;
// animation
todo.classList.add("fall");
todo.addEventListener("transitionend", function() {
todo.remove();
});
}
// check mark
if(item.classList[0] === "complete-btn"){
const todo = item.parentElement;
todo.classList.toggle('completed');
}
}
function filterTodo(e) {
const todos = todoList.childNodes;
todos.forEach(function(todo) {
switch (e.target.value) {
case "all":
todo.style.display = "flex";
break;
case "completed":
if (todo.classList.contains("completed")) {
todo.style.display = "flex";
} else {
todo.style.display = "none";
}
break;
case "uncompleted":
if (!todo.classList.contains("completed")) {
todo.style.display = "flex";
} else {
todo.style.display = "none";
}
}
});
}
The first test I created was to check if a todo is created
const todo = require('./app')
test('add a todo', () => {
expect(todo("buy milk".toBe("buy milk")))
})
But the test failed.
Upvotes: 2
Views: 3562
Reputation: 236
First you need to decide whether you're testing the UI or the system/engine the UI wraps around. Besides the missing )
after todo("buy milk"
, you are trying to test the engine not the UI.
In your case you should look into splitting the actual to do engine code from the UI layer. Then you can test CRUD of the to do.
Lets take a basic example:
const Todo = function() {
let list = [];
let items = {};
return {
create: function(task) {
let id = Date.now();
items[id] = { id, task };
list.push(id);
return id;
},
read: function(id) {
return items[id];
},
readAll: function() {
return list.map(id => items[id]);
},
delete: function(id) {
list = list.filter(itemId => itemId !== id);
delete items[id];
return true;
}
}
}
This is a testable todo engine and tests would look like this (using mocha and chai):
const { expect } = require("chai");
const Todo = require("./Todo.js"); // replace with your file
describe("Todo", function() {
const todo = Todo();
it("should create a todo item and return an ID", function() {
let id = todo.create("My first todo");
expect(id).to.be.a("integer");
});
it("should create a todo item with text 'My second todo'", function() {
let id = todo.create("My second todo");
let text = todo.read(id);
expect(text).to.equal("My second todo");
});
it("should return an array with two todo items", function() {
let items = todo.readAll();
// you can also test for exact strings
expect(items.length).to.equal(2);
});
it("should delete first item", function() {
let items = todo.readAll();
let id = items[0].id;
todo.delete(id);
items = todo.readAll();
expect(items.length).to.equal(1);
});
});
When you get to front-end testing, you will use a tool like Cypress or Puppeteer
Upvotes: 3