import {test} from 'node:test';
import assert from 'node:assert/strict';
import {TodoList} from './main.js';
// Collects every event of a list as [event, number, text, done].
const record = (list) => {
const events = [];
list.on('added', (item, n) => events.push(['added', n, item.text, item.done]));
list.on('done', (item, n) => events.push(['done', n, item.text, item.done]));
return events;
};
test('add stores the to-do and emits added with the item and its number', () => {
const list = new TodoList();
const events = record(list);
list.add('tea');
list.add('milk');
assert.deepEqual(list.items, [{text: 'tea', done: false}, {text: 'milk', done: false}], 'items is ' + JSON.stringify(list.items));
assert.deepEqual(events, [['added', 1, 'tea', false], ['added', 2, 'milk', false]], 'the events were ' + JSON.stringify(events));
});
test('add with an empty text throws and changes nothing', () => {
const list = new TodoList();
const events = record(list);
assert.throws(() => list.add(''), {message: 'add needs a text, such as add buy milk'}, "add('') should throw: add needs a text, such as add buy milk");
assert.equal(list.items.length + events.length, 0, "add('') should neither store a to-do nor emit an event");
});
test('done marks the to-do and emits done with the item and its number', () => {
const list = new TodoList();
const events = record(list);
list.add('tea');
list.add('milk');
list.done('2');
assert.deepEqual(events.slice(2), [['done', 2, 'milk', true]], 'after done 2 the events were ' + JSON.stringify(events.slice(2)));
assert.equal(list.items[0].done, false, 'done 2 should leave tea unfinished');
});
test('a second done for the same to-do emits nothing', () => {
const list = new TodoList();
const events = record(list);
list.add('tea');
list.done('1');
list.done('1');
assert.equal(events.filter((e) => e[0] === 'done').length, 1, 'done 1 twice should emit done once');
});
test('done with a wrong number throws a RangeError and changes nothing', () => {
const list = new TodoList();
list.add('tea');
for (const arg of ['0', '2', 'x', '']) {
assert.throws(() => list.done(arg), {name: 'RangeError', message: 'no to-do "' + arg + '"'}, 'done(' + JSON.stringify(arg) + ') should throw RangeError: no to-do "' + arg + '"');
}
assert.equal(list.items[0].done, false, 'tea should still be unfinished');
});