Skip to content
Open
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
11 changes: 10 additions & 1 deletion lib/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,13 @@ function search(term) {
return matches(load().notes, term);
}

module.exports = { all, add, remove, search, matches };
function edit(id, newText) {
const data = load();
const note = data.notes.find(n => n.id === id);
if (!note) return null;
note.text = newText;
save(data);
return note;
}

module.exports = { all, add, remove, search, matches, edit };
18 changes: 17 additions & 1 deletion notes.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,24 @@ function main() {
console.log(ok ? `Deleted note #${id}` : `No note #${id} found`);
break;
}
case "edit": {
const id = Number(rest[0]);
const text = rest.slice(1).join(" ").trim();
if (!id || !text) {
console.log("Usage: notes edit <id> <new text>");
return;
}
const note = store.edit(id, text);
console.log(note ? `Updated note #${id}: ${note.text}` : `No note #${id} found`);
break;
}
case "count": {
const total = store.all().length;
console.log(`You have ${total} note${total === 1 ? "" : "s"}.`);
break;
}
default:
console.log("Commands: add <text> | list | search <term> | delete <id>");
console.log("Commands: add <text> | list | search <term> | delete <id> | edit <id> <new text> | count");
console.log(`(Session locks after ${config.SESSION_TIMEOUT_MINUTES} minutes of inactivity.)`);
}
}
Expand Down
30 changes: 29 additions & 1 deletion tests/notes.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
const test = require("node:test");
const assert = require("node:assert");
const fs = require("fs");
const path = require("path");

const { matches } = require("../lib/store");
const { matches, edit } = require("../lib/store");

const NOTES_FILE = path.join(__dirname, "..", "notes.json");

function withCleanStore(notes, fn) {
const prev = fs.existsSync(NOTES_FILE) ? fs.readFileSync(NOTES_FILE) : null;
const nextId = notes.length ? Math.max(...notes.map(n => n.id)) + 1 : 1;
fs.writeFileSync(NOTES_FILE, JSON.stringify({ nextId, notes }, null, 2));
try { return fn(); } finally {
prev ? fs.writeFileSync(NOTES_FILE, prev) : fs.unlinkSync(NOTES_FILE);
}
}

const notes = [
{ id: 1, text: "buy milk" },
Expand All @@ -24,3 +37,18 @@ test("search returns nothing when no note contains the term", () => {
const result = matches(notes, "xyz");
assert.strictEqual(result.length, 0);
});

test("edit updates the text of an existing note", () => {
withCleanStore([{ id: 1, text: "original" }], () => {
const updated = edit(1, "revised");
assert.strictEqual(updated.id, 1);
assert.strictEqual(updated.text, "revised");
});
});

test("edit returns null when the note id does not exist", () => {
withCleanStore([{ id: 1, text: "original" }], () => {
const result = edit(999, "revised");
assert.strictEqual(result, null);
});
});