dnote/pkg/cli/cmd/view/book_test.go
2025-11-07 23:53:41 -08:00

184 lines
5.2 KiB
Go

/* Copyright 2025 Dnote Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package view
import (
"bytes"
"fmt"
"strings"
"testing"
"github.com/dnote/dnote/pkg/assert"
"github.com/dnote/dnote/pkg/cli/context"
"github.com/dnote/dnote/pkg/cli/database"
)
func TestGetNewlineIdx(t *testing.T) {
testCases := []struct {
input string
expected int
}{
{
input: "hello\nworld",
expected: 5,
},
{
input: "hello\r\nworld",
expected: 5,
},
{
input: "no newline here",
expected: -1,
},
{
input: "",
expected: -1,
},
{
input: "\n",
expected: 0,
},
{
input: "\r\n",
expected: 0,
},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("input: %q", tc.input), func(t *testing.T) {
got := getNewlineIdx(tc.input)
assert.Equal(t, got, tc.expected, "newline index mismatch")
})
}
}
func TestFormatBody(t *testing.T) {
testCases := []struct {
input string
expectedBody string
expectedExcerpt bool
}{
{
input: "single line",
expectedBody: "single line",
expectedExcerpt: false,
},
{
input: "first line\nsecond line",
expectedBody: "first line",
expectedExcerpt: true,
},
{
input: "first line\r\nsecond line",
expectedBody: "first line",
expectedExcerpt: true,
},
{
input: " spaced line ",
expectedBody: "spaced line",
expectedExcerpt: false,
},
{
input: " first line \nsecond line",
expectedBody: "first line",
expectedExcerpt: true,
},
{
input: "",
expectedBody: "",
expectedExcerpt: false,
},
{
input: "line with trailing newline\n",
expectedBody: "line with trailing newline",
expectedExcerpt: false,
},
{
input: "line with trailing newlines\n\n",
expectedBody: "line with trailing newlines",
expectedExcerpt: false,
},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("input: %q", tc.input), func(t *testing.T) {
gotBody, gotExcerpt := formatBody(tc.input)
assert.Equal(t, gotBody, tc.expectedBody, "formatted body mismatch")
assert.Equal(t, gotExcerpt, tc.expectedExcerpt, "excerpt flag mismatch")
})
}
}
func TestListNotes(t *testing.T) {
// Setup
db := database.InitTestMemoryDB(t)
defer db.Close()
bookUUID := "js-book-uuid"
database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", bookUUID, "javascript")
database.MustExec(t, "inserting note 1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?)", "note-1", bookUUID, "first note", 1515199943)
database.MustExec(t, "inserting note 2", db, "INSERT INTO notes (uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?)", "note-2", bookUUID, "multiline note\nwith second line", 1515199945)
ctx := context.DnoteCtx{DB: db}
var buf bytes.Buffer
// Execute
err := listNotes(ctx, &buf, "javascript")
if err != nil {
t.Fatal(err)
}
got := buf.String()
// Verify output
assert.Equal(t, strings.Contains(got, "on book javascript"), true, "should show book name")
assert.Equal(t, strings.Contains(got, "first note"), true, "should contain first note")
assert.Equal(t, strings.Contains(got, "multiline note"), true, "should show first line of multiline note")
assert.Equal(t, strings.Contains(got, "[---More---]"), true, "should show more indicator for multiline note")
assert.Equal(t, strings.Contains(got, "with second line"), false, "should not show second line of multiline note")
}
func TestListBooks(t *testing.T) {
// Setup
db := database.InitTestMemoryDB(t)
defer db.Close()
b1UUID := "js-book-uuid"
b2UUID := "linux-book-uuid"
database.MustExec(t, "inserting book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "javascript")
database.MustExec(t, "inserting book 2", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "linux")
// Add notes to test count
database.MustExec(t, "inserting note 1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?)", "note-1", b1UUID, "note body 1", 1515199943)
database.MustExec(t, "inserting note 2", db, "INSERT INTO notes (uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?)", "note-2", b1UUID, "note body 2", 1515199944)
ctx := context.DnoteCtx{DB: db}
var buf bytes.Buffer
// Execute
err := listBooks(ctx, &buf, false)
if err != nil {
t.Fatal(err)
}
got := buf.String()
// Verify output
assert.Equal(t, strings.Contains(got, "javascript"), true, "should contain javascript book")
assert.Equal(t, strings.Contains(got, "linux"), true, "should contain linux book")
assert.Equal(t, strings.Contains(got, "(2)"), true, "should show 2 notes for javascript")
}