diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..45dc303a
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,25 @@
+language: go
+dist: xenial
+
+go:
+ - 1.12
+
+addons:
+ postgresql: "10"
+
+env:
+ - NODE_VERSION=10.15.0
+
+before_script:
+ - nvm install "$NODE_VERSION"
+ - nvm use "$NODE_VERSION"
+ - node --version
+ - psql -c "CREATE DATABASE dnote_test;" -U postgres
+
+install:
+ - make install
+
+script:
+ - make test-cli
+ - make test-api
+ - make test-web
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..a247cf8c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,56 @@
+DEP := $(shell command -v dep 2> /dev/null)
+NPM := $(shell command -v npm 2> /dev/null)
+
+## installation
+install-cli:
+ifndef DEP
+ @echo "==> installing dep"
+ @curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
+endif
+
+ @echo "==> installing CLI dependencies"
+ @(cd ${GOPATH}/src/github.com/dnote/dnote/pkg/cli && dep ensure)
+.PHONY: install-cli
+
+install-web:
+ifndef NPM
+ @echo "npm not found"
+ exit 1
+endif
+
+ @echo "==> installing web dependencies"
+ @(cd ${GOPATH}/src/github.com/dnote/dnote/web && npm install)
+.PHONY: install-web
+
+install-server:
+ @echo "==> installing server dependencies"
+ @(cd ${GOPATH}/src/github.com/dnote/dnote/pkg/server && dep ensure)
+.PHONY: install-server
+
+install: install-cli install-web install-server
+.PHONY: install
+
+## test
+test-cli:
+ @echo "==> running CLI test"
+ @${GOPATH}/src/github.com/dnote/dnote/pkg/cli/scripts/test.sh
+.PHONY: test-cli
+
+test-api:
+ @echo "==> running API test"
+ @${GOPATH}/src/github.com/dnote/dnote/pkg/server/api/scripts/test-local.sh
+.PHONY: test-api
+
+test-web:
+ @echo "==> running web test"
+ @(cd ${GOPATH}/src/github.com/dnote/dnote/web && npm run test)
+.PHONY: test-web
+
+test: test-cli test-api test-web
+.PHONY: test
+
+## build
+build-web:
+ @echo "==> building web"
+ @${GOPATH}/src/github.com/dnote/dnote/web/scripts/build-prod.sh
+.PHONY: build-web
diff --git a/README.md b/README.md
index 477fd2a0..9dc24bbd 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
Dnote is a simple notebook for developers.
-[](https://semaphoreci.com/dnote/dnote-2)
+[](https://travis-ci.org/dnote/dnote)
## What is Dnote?
diff --git a/cli/core/core.go b/cli/core/core.go
deleted file mode 100644
index db33ddf6..00000000
--- a/cli/core/core.go
+++ /dev/null
@@ -1,358 +0,0 @@
-/* Copyright (C) 2019 Monomax Software Pty Ltd
- *
- * This file is part of Dnote CLI.
- *
- * Dnote CLI is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote CLI is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dnote CLI. If not, see .
- */
-
-package core
-
-import (
- "database/sql"
- "fmt"
- "io/ioutil"
- "os"
- "os/exec"
- "strconv"
- "strings"
- "time"
-
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
- "github.com/dnote/dnote/cli/utils"
- "github.com/pkg/errors"
- "github.com/satori/go.uuid"
- "github.com/spf13/cobra"
- "gopkg.in/yaml.v2"
-)
-
-var (
- // ConfigFilename is the name of the config file
- ConfigFilename = "dnoterc"
- // TmpContentFilename is the name of the temporary file that holds editor input
- TmpContentFilename = "DNOTE_TMPCONTENT.md"
-)
-
-// RunEFunc is a function type of dnote commands
-type RunEFunc func(*cobra.Command, []string) error
-
-// GetConfigPath returns the path to the dnote config file
-func GetConfigPath(ctx infra.DnoteCtx) string {
- return fmt.Sprintf("%s/%s", ctx.DnoteDir, ConfigFilename)
-}
-
-// GetDnoteTmpContentPath returns the path to the temporary file containing
-// content being added or edited
-func GetDnoteTmpContentPath(ctx infra.DnoteCtx) string {
- return fmt.Sprintf("%s/%s", ctx.DnoteDir, TmpContentFilename)
-}
-
-// GetBookUUID returns a uuid of a book given a label
-func GetBookUUID(ctx infra.DnoteCtx, label string) (string, error) {
- db := ctx.DB
-
- var ret string
- err := db.QueryRow("SELECT uuid FROM books WHERE label = ?", label).Scan(&ret)
- if err == sql.ErrNoRows {
- return ret, errors.Errorf("book '%s' not found", label)
- } else if err != nil {
- return ret, errors.Wrap(err, "querying the book")
- }
-
- return ret, nil
-}
-
-// getEditorCommand returns the system's editor command with appropriate flags,
-// if necessary, to make the command wait until editor is close to exit.
-func getEditorCommand() string {
- editor := os.Getenv("EDITOR")
-
- var ret string
-
- switch editor {
- case "atom":
- ret = "atom -w"
- case "subl":
- ret = "subl -n -w"
- case "mate":
- ret = "mate -w"
- case "vim":
- ret = "vim"
- case "nano":
- ret = "nano"
- case "emacs":
- ret = "emacs"
- case "nvim":
- ret = "nvim"
- default:
- ret = "vi"
- }
-
- return ret
-}
-
-// InitFiles creates, if necessary, the dnote directory and files inside
-func InitFiles(ctx infra.DnoteCtx) error {
- if err := initDnoteDir(ctx); err != nil {
- return errors.Wrap(err, "creating the dnote dir")
- }
- if err := initConfigFile(ctx); err != nil {
- return errors.Wrap(err, "generating the config file")
- }
-
- return nil
-}
-
-// initConfigFile populates a new config file if it does not exist yet
-func initConfigFile(ctx infra.DnoteCtx) error {
- path := GetConfigPath(ctx)
-
- if utils.FileExists(path) {
- return nil
- }
-
- editor := getEditorCommand()
-
- config := infra.Config{
- Editor: editor,
- }
-
- b, err := yaml.Marshal(config)
- if err != nil {
- return errors.Wrap(err, "marshalling config into YAML")
- }
-
- err = ioutil.WriteFile(path, b, 0644)
- if err != nil {
- return errors.Wrap(err, "writing the config file")
- }
-
- return nil
-}
-
-// initDnoteDir initializes dnote directory if it does not exist yet
-func initDnoteDir(ctx infra.DnoteCtx) error {
- path := ctx.DnoteDir
-
- if utils.FileExists(path) {
- return nil
- }
-
- if err := os.MkdirAll(path, 0755); err != nil {
- return errors.Wrap(err, "Failed to create dnote directory")
- }
-
- return nil
-}
-
-// WriteConfig writes the config to the config file
-func WriteConfig(ctx infra.DnoteCtx, config infra.Config) error {
- d, err := yaml.Marshal(config)
- if err != nil {
- return errors.Wrap(err, "marhsalling config")
- }
-
- configPath := GetConfigPath(ctx)
-
- err = ioutil.WriteFile(configPath, d, 0644)
- if err != nil {
- errors.Wrap(err, "writing the config file")
- }
-
- return nil
-}
-
-// LogAction logs action and updates the last_action
-func LogAction(tx *sql.Tx, schema int, actionType, data string, timestamp int64) error {
- uuid := uuid.NewV4().String()
-
- _, err := tx.Exec(`INSERT INTO actions (uuid, schema, type, data, timestamp)
- VALUES (?, ?, ?, ?, ?)`, uuid, schema, actionType, data, timestamp)
- if err != nil {
- return errors.Wrap(err, "inserting an action")
- }
-
- _, err = tx.Exec("UPDATE system SET value = ? WHERE key = ?", timestamp, "last_action")
- if err != nil {
- return errors.Wrap(err, "updating last_action")
- }
-
- return nil
-}
-
-// ReadConfig reads the config file
-func ReadConfig(ctx infra.DnoteCtx) (infra.Config, error) {
- var ret infra.Config
-
- configPath := GetConfigPath(ctx)
- b, err := ioutil.ReadFile(configPath)
- if err != nil {
- return ret, errors.Wrap(err, "reading config file")
- }
-
- err = yaml.Unmarshal(b, &ret)
- if err != nil {
- return ret, errors.Wrap(err, "unmarshalling config")
- }
-
- return ret, nil
-}
-
-// SanitizeContent sanitizes note content
-func SanitizeContent(s string) string {
- var ret string
-
- ret = strings.Trim(s, " ")
-
- // Remove newline at the end of the file because POSIX defines a line as
- // characters followed by a newline
- ret = strings.TrimSuffix(ret, "\n")
- ret = strings.TrimSuffix(ret, "\r\n")
-
- return ret
-}
-
-func newEditorCmd(ctx infra.DnoteCtx, fpath string) (*exec.Cmd, error) {
- config, err := ReadConfig(ctx)
- if err != nil {
- return nil, errors.Wrap(err, "reading config")
- }
-
- args := strings.Fields(config.Editor)
- args = append(args, fpath)
-
- return exec.Command(args[0], args[1:]...), nil
-}
-
-// GetEditorInput gets the user input by launching a text editor and waiting for
-// it to exit
-func GetEditorInput(ctx infra.DnoteCtx, fpath string, content *string) error {
- if !utils.FileExists(fpath) {
- f, err := os.Create(fpath)
- if err != nil {
- return errors.Wrap(err, "creating a temporary content file")
- }
- err = f.Close()
- if err != nil {
- return errors.Wrap(err, "closing the temporary content file")
- }
- }
-
- cmd, err := newEditorCmd(ctx, fpath)
- if err != nil {
- return errors.Wrap(err, "creating an editor command")
- }
-
- cmd.Stdin = os.Stdin
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
-
- err = cmd.Start()
- if err != nil {
- return errors.Wrapf(err, "launching an editor")
- }
-
- err = cmd.Wait()
- if err != nil {
- return errors.Wrap(err, "waiting for the editor")
- }
-
- b, err := ioutil.ReadFile(fpath)
- if err != nil {
- return errors.Wrap(err, "reading the temporary content file")
- }
-
- err = os.Remove(fpath)
- if err != nil {
- return errors.Wrap(err, "removing the temporary content file")
- }
-
- raw := string(b)
- c := SanitizeContent(raw)
-
- *content = c
-
- return nil
-}
-
-func initSystemKV(db *infra.DB, key string, val string) error {
- var count int
- if err := db.QueryRow("SELECT count(*) FROM system WHERE key = ?", key).Scan(&count); err != nil {
- return errors.Wrapf(err, "counting %s", key)
- }
-
- if count > 0 {
- return nil
- }
-
- if _, err := db.Exec("INSERT INTO system (key, value) VALUES (?, ?)", key, val); err != nil {
- db.Rollback()
- return errors.Wrapf(err, "inserting %s %s", key, val)
-
- }
-
- return nil
-}
-
-// InitSystem inserts system data if missing
-func InitSystem(ctx infra.DnoteCtx) error {
- db := ctx.DB
-
- tx, err := db.Begin()
- if err != nil {
- return errors.Wrap(err, "beginning a transaction")
- }
-
- nowStr := strconv.FormatInt(time.Now().Unix(), 10)
- if err := initSystemKV(tx, infra.SystemLastUpgrade, nowStr); err != nil {
- return errors.Wrapf(err, "initializing system config for %s", infra.SystemLastUpgrade)
- }
- if err := initSystemKV(tx, infra.SystemLastMaxUSN, "0"); err != nil {
- return errors.Wrapf(err, "initializing system config for %s", infra.SystemLastMaxUSN)
- }
- if err := initSystemKV(tx, infra.SystemLastSyncAt, "0"); err != nil {
- return errors.Wrapf(err, "initializing system config for %s", infra.SystemLastSyncAt)
- }
-
- tx.Commit()
-
- return nil
-}
-
-// GetValidSession returns a session key from the local storage if one exists and is not expired
-// If one does not exist or is expired, it prints out an instruction and returns false
-func GetValidSession(ctx infra.DnoteCtx) (string, bool, error) {
- db := ctx.DB
-
- var sessionKey string
- var sessionKeyExpires int64
-
- if err := GetSystem(db, infra.SystemSessionKey, &sessionKey); err != nil {
- return "", false, errors.Wrap(err, "getting session key")
- }
- if err := GetSystem(db, infra.SystemSessionKeyExpiry, &sessionKeyExpires); err != nil {
- return "", false, errors.Wrap(err, "getting session key expiry")
- }
-
- if sessionKey == "" {
- log.Error("login required. please run `dnote login`\n")
- return "", false, nil
- }
- if sessionKeyExpires < time.Now().Unix() {
- log.Error("sesison expired. please run `dnote login`\n")
- return "", false, nil
- }
-
- return sessionKey, true, nil
-}
diff --git a/cli/core/queries.go b/cli/core/queries.go
deleted file mode 100644
index cd50013f..00000000
--- a/cli/core/queries.go
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright (C) 2019 Monomax Software Pty Ltd
- *
- * This file is part of Dnote CLI.
- *
- * Dnote CLI is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote CLI is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dnote CLI. If not, see .
- */
-
-package core
-
-import (
- "database/sql"
-
- "github.com/dnote/dnote/cli/infra"
- "github.com/pkg/errors"
-)
-
-// NoteInfo is a basic information about a note
-type NoteInfo struct {
- RowID int
- BookLabel string
- UUID string
- Content string
- AddedOn int64
- EditedOn int64
-}
-
-// GetNoteInfo returns a NoteInfo for the note with the given noteRowID
-func GetNoteInfo(ctx infra.DnoteCtx, noteRowID string) (NoteInfo, error) {
- var ret NoteInfo
-
- db := ctx.DB
- err := db.QueryRow(`SELECT books.label, notes.uuid, notes.body, notes.added_on, notes.edited_on, notes.rowid
- FROM notes
- INNER JOIN books ON books.uuid = notes.book_uuid
- WHERE notes.rowid = ? AND notes.deleted = false`, noteRowID).
- Scan(&ret.BookLabel, &ret.UUID, &ret.Content, &ret.AddedOn, &ret.EditedOn, &ret.RowID)
- if err == sql.ErrNoRows {
- return ret, errors.Errorf("note %s not found", noteRowID)
- } else if err != nil {
- return ret, errors.Wrap(err, "querying the note")
- }
-
- return ret, nil
-
-}
diff --git a/cli/infra/main.go b/cli/infra/main.go
deleted file mode 100644
index c64179c3..00000000
--- a/cli/infra/main.go
+++ /dev/null
@@ -1,225 +0,0 @@
-/* Copyright (C) 2019 Monomax Software Pty Ltd
- *
- * This file is part of Dnote CLI.
- *
- * Dnote CLI is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote CLI is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dnote CLI. If not, see .
- */
-
-// Package infra defines dnote structure
-package infra
-
-import (
- "database/sql"
- "encoding/base64"
- "fmt"
- "os"
- "os/user"
-
- // use sqlite
- _ "github.com/mattn/go-sqlite3"
-
- "github.com/pkg/errors"
-)
-
-var (
- // DnoteDirName is the name of the directory containing dnote files
- DnoteDirName = ".dnote"
-
- // SystemSchema is the key for schema in the system table
- SystemSchema = "schema"
- // SystemRemoteSchema is the key for remote schema in the system table
- SystemRemoteSchema = "remote_schema"
- // SystemLastSyncAt is the timestamp of the server at the last sync
- SystemLastSyncAt = "last_sync_time"
- // SystemLastMaxUSN is the user's max_usn from the server at the alst sync
- SystemLastMaxUSN = "last_max_usn"
- // SystemLastUpgrade is the timestamp at which the system more recently checked for an upgrade
- SystemLastUpgrade = "last_upgrade"
- // SystemCipherKey is the encryption key
- SystemCipherKey = "enc_key"
- // SystemSessionKey is the session key
- SystemSessionKey = "session_token"
- // SystemSessionKeyExpiry is the timestamp at which the session key will expire
- SystemSessionKeyExpiry = "session_token_expiry"
-)
-
-// DnoteCtx is a context holding the information of the current runtime
-type DnoteCtx struct {
- HomeDir string
- DnoteDir string
- APIEndpoint string
- Version string
- DB *DB
- SessionKey string
- SessionKeyExpiry int64
- CipherKey []byte
-}
-
-// Config holds dnote configuration
-type Config struct {
- Editor string
-}
-
-// NewCtx returns a new dnote context
-func NewCtx(apiEndpoint, versionTag string) (DnoteCtx, error) {
- homeDir, err := getHomeDir()
- if err != nil {
- return DnoteCtx{}, errors.Wrap(err, "Failed to get home dir")
- }
- dnoteDir := getDnoteDir(homeDir)
-
- dnoteDBPath := fmt.Sprintf("%s/dnote.db", dnoteDir)
- db, err := OpenDB(dnoteDBPath)
- if err != nil {
- return DnoteCtx{}, errors.Wrap(err, "conntecting to db")
- }
-
- ret := DnoteCtx{
- HomeDir: homeDir,
- DnoteDir: dnoteDir,
- APIEndpoint: apiEndpoint,
- Version: versionTag,
- DB: db,
- }
-
- return ret, nil
-}
-
-// SetupCtx populates context and returns a new context
-func SetupCtx(ctx DnoteCtx) (DnoteCtx, error) {
- db := ctx.DB
-
- var sessionKey, cipherKeyB64 string
- var sessionKeyExpiry int64
-
- err := db.QueryRow("SELECT value FROM system WHERE key = ?", SystemSessionKey).Scan(&sessionKey)
- if err != nil && err != sql.ErrNoRows {
- return ctx, errors.Wrap(err, "finding sesison key")
- }
- err = db.QueryRow("SELECT value FROM system WHERE key = ?", SystemCipherKey).Scan(&cipherKeyB64)
- if err != nil && err != sql.ErrNoRows {
- return ctx, errors.Wrap(err, "finding sesison key")
- }
- err = db.QueryRow("SELECT value FROM system WHERE key = ?", SystemSessionKeyExpiry).Scan(&sessionKeyExpiry)
- if err != nil && err != sql.ErrNoRows {
- return ctx, errors.Wrap(err, "finding sesison key expiry")
- }
-
- cipherKey, err := base64.StdEncoding.DecodeString(cipherKeyB64)
- if err != nil {
- return ctx, errors.Wrap(err, "decoding cipherKey from base64")
- }
-
- ret := DnoteCtx{
- HomeDir: ctx.HomeDir,
- DnoteDir: ctx.DnoteDir,
- APIEndpoint: ctx.APIEndpoint,
- Version: ctx.Version,
- DB: ctx.DB,
- SessionKey: sessionKey,
- SessionKeyExpiry: sessionKeyExpiry,
- CipherKey: cipherKey,
- }
-
- return ret, nil
-}
-
-func getDnoteDir(homeDir string) string {
- var ret string
-
- dnoteDirEnv := os.Getenv("DNOTE_DIR")
- if dnoteDirEnv == "" {
- ret = fmt.Sprintf("%s/%s", homeDir, DnoteDirName)
- } else {
- ret = dnoteDirEnv
- }
-
- return ret
-}
-
-func getHomeDir() (string, error) {
- homeDirEnv := os.Getenv("DNOTE_HOME_DIR")
- if homeDirEnv != "" {
- return homeDirEnv, nil
- }
-
- usr, err := user.Current()
- if err != nil {
- return "", errors.Wrap(err, "Failed to get current user")
- }
-
- return usr.HomeDir, nil
-}
-
-// InitDB initializes the database.
-// Ideally this process must be a part of migration sequence. But it is performed
-// seaprately because it is a prerequisite for legacy migration.
-func InitDB(ctx DnoteCtx) error {
- db := ctx.DB
-
- _, err := db.Exec(`CREATE TABLE IF NOT EXISTS notes
- (
- id integer PRIMARY KEY AUTOINCREMENT,
- uuid text NOT NULL,
- book_uuid text NOT NULL,
- content text NOT NULL,
- added_on integer NOT NULL,
- edited_on integer DEFAULT 0,
- public bool DEFAULT false
- )`)
- if err != nil {
- return errors.Wrap(err, "creating notes table")
- }
-
- _, err = db.Exec(`CREATE TABLE IF NOT EXISTS books
- (
- uuid text PRIMARY KEY,
- label text NOT NULL
- )`)
- if err != nil {
- return errors.Wrap(err, "creating books table")
- }
-
- _, err = db.Exec(`CREATE TABLE IF NOT EXISTS system
- (
- key string NOT NULL,
- value text NOT NULL
- )`)
- if err != nil {
- return errors.Wrap(err, "creating system table")
- }
-
- _, err = db.Exec(`CREATE TABLE IF NOT EXISTS actions
- (
- uuid text PRIMARY KEY,
- schema integer NOT NULL,
- type text NOT NULL,
- data text NOT NULL,
- timestamp integer NOT NULL
- )`)
- if err != nil {
- return errors.Wrap(err, "creating actions table")
- }
-
- _, err = db.Exec(`
- CREATE UNIQUE INDEX IF NOT EXISTS idx_books_label ON books(label);
- CREATE UNIQUE INDEX IF NOT EXISTS idx_notes_uuid ON notes(uuid);
- CREATE UNIQUE INDEX IF NOT EXISTS idx_books_uuid ON books(uuid);
- CREATE INDEX IF NOT EXISTS idx_notes_book_uuid ON notes(book_uuid);`)
- if err != nil {
- return errors.Wrap(err, "creating indices")
- }
-
- return nil
-}
diff --git a/cli/main.go b/cli/main.go
deleted file mode 100644
index 212345d1..00000000
--- a/cli/main.go
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright (C) 2019 Monomax Software Pty Ltd
- *
- * This file is part of Dnote CLI.
- *
- * Dnote CLI is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote CLI is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dnote CLI. If not, see .
- */
-
-package main
-
-import (
- "os"
-
- "github.com/dnote/dnote/cli/cmd/root"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
- _ "github.com/mattn/go-sqlite3"
- "github.com/pkg/errors"
-
- // commands
- "github.com/dnote/dnote/cli/cmd/add"
- "github.com/dnote/dnote/cli/cmd/cat"
- "github.com/dnote/dnote/cli/cmd/edit"
- "github.com/dnote/dnote/cli/cmd/find"
- "github.com/dnote/dnote/cli/cmd/login"
- "github.com/dnote/dnote/cli/cmd/logout"
- "github.com/dnote/dnote/cli/cmd/ls"
- "github.com/dnote/dnote/cli/cmd/remove"
- "github.com/dnote/dnote/cli/cmd/sync"
- "github.com/dnote/dnote/cli/cmd/version"
- "github.com/dnote/dnote/cli/cmd/view"
-)
-
-// apiEndpoint and versionTag are populated during link time
-var apiEndpoint string
-var versionTag = "master"
-
-func main() {
- ctx, err := infra.NewCtx(apiEndpoint, versionTag)
- if err != nil {
- panic(errors.Wrap(err, "initializing context"))
- }
- defer ctx.DB.Close()
-
- if err := root.Prepare(ctx); err != nil {
- panic(errors.Wrap(err, "preparing dnote run"))
- }
-
- ctx, err = infra.SetupCtx(ctx)
- if err != nil {
- panic(errors.Wrap(err, "setting up context"))
- }
-
- root.Register(remove.NewCmd(ctx))
- root.Register(edit.NewCmd(ctx))
- root.Register(login.NewCmd(ctx))
- root.Register(logout.NewCmd(ctx))
- root.Register(add.NewCmd(ctx))
- root.Register(ls.NewCmd(ctx))
- root.Register(sync.NewCmd(ctx))
- root.Register(version.NewCmd(ctx))
- root.Register(cat.NewCmd(ctx))
- root.Register(view.NewCmd(ctx))
- root.Register(find.NewCmd(ctx))
-
- if err := root.Execute(); err != nil {
- log.Errorf("%s\n", err.Error())
- os.Exit(1)
- }
-}
diff --git a/cli/main_test.go b/cli/main_test.go
deleted file mode 100644
index 8d0aeb1d..00000000
--- a/cli/main_test.go
+++ /dev/null
@@ -1,339 +0,0 @@
-/* Copyright (C) 2019 Monomax Software Pty Ltd
- *
- * This file is part of Dnote CLI.
- *
- * Dnote CLI is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote CLI is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dnote CLI. If not, see .
- */
-
-package main
-
-import (
- "fmt"
- "log"
- "os"
- "os/exec"
- "testing"
-
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/testutils"
- "github.com/dnote/dnote/cli/utils"
- "github.com/pkg/errors"
-)
-
-var binaryName = "test-dnote"
-
-func TestMain(m *testing.M) {
- if err := exec.Command("go", "build", "--tags", "fts5", "-o", binaryName).Run(); err != nil {
- log.Print(errors.Wrap(err, "building a binary").Error())
- os.Exit(1)
- }
-
- os.Exit(m.Run())
-}
-
-func TestInit(t *testing.T) {
- // Set up
- ctx := testutils.InitEnv(t, "./tmp", "./testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- // Execute
- testutils.RunDnoteCmd(t, ctx, binaryName)
-
- // Test
- if !utils.FileExists(ctx.DnoteDir) {
- t.Errorf("dnote directory was not initialized")
- }
- if !utils.FileExists(fmt.Sprintf("%s/%s", ctx.DnoteDir, core.ConfigFilename)) {
- t.Errorf("config file was not initialized")
- }
-
- db := ctx.DB
-
- var notesTableCount, booksTableCount, systemTableCount int
- testutils.MustScan(t, "counting notes",
- db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type = ? AND name = ?", "table", "notes"), ¬esTableCount)
- testutils.MustScan(t, "counting books",
- db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type = ? AND name = ?", "table", "books"), &booksTableCount)
- testutils.MustScan(t, "counting system",
- db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type = ? AND name = ?", "table", "system"), &systemTableCount)
-
- testutils.AssertEqual(t, notesTableCount, 1, "notes table count mismatch")
- testutils.AssertEqual(t, booksTableCount, 1, "books table count mismatch")
- testutils.AssertEqual(t, systemTableCount, 1, "system table count mismatch")
-
- // test that all default system configurations are generated
- var lastUpgrade, lastMaxUSN, lastSyncAt string
- testutils.MustScan(t, "scanning last upgrade",
- db.QueryRow("SELECT value FROM system WHERE key = ?", infra.SystemLastUpgrade), &lastUpgrade)
- testutils.MustScan(t, "scanning last max usn",
- db.QueryRow("SELECT value FROM system WHERE key = ?", infra.SystemLastMaxUSN), &lastMaxUSN)
- testutils.MustScan(t, "scanning last sync at",
- db.QueryRow("SELECT value FROM system WHERE key = ?", infra.SystemLastSyncAt), &lastSyncAt)
-
- testutils.AssertNotEqual(t, lastUpgrade, "", "last upgrade should not be empty")
- testutils.AssertNotEqual(t, lastMaxUSN, "", "last max usn should not be empty")
- testutils.AssertNotEqual(t, lastSyncAt, "", "last sync at should not be empty")
-}
-
-func TestAddNote_NewBook_BodyFlag(t *testing.T) {
- // Set up
- ctx := testutils.InitEnv(t, "./tmp", "./testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- // Execute
- testutils.RunDnoteCmd(t, ctx, binaryName, "add", "js", "-c", "foo")
-
- // Test
- db := ctx.DB
-
- var noteCount, bookCount int
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
-
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch")
- testutils.AssertEqualf(t, noteCount, 1, "note count mismatch")
-
- var book core.Book
- testutils.MustScan(t, "getting book", db.QueryRow("SELECT uuid, dirty FROM books where label = ?", "js"), &book.UUID, &book.Dirty)
- var note core.Note
- testutils.MustScan(t, "getting note",
- db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes where book_uuid = ?", book.UUID), ¬e.UUID, ¬e.Body, ¬e.AddedOn, ¬e.Dirty)
-
- testutils.AssertEqual(t, book.Dirty, true, "Book dirty mismatch")
-
- testutils.AssertNotEqual(t, note.UUID, "", "Note should have UUID")
- testutils.AssertEqual(t, note.Body, "foo", "Note body mismatch")
- testutils.AssertEqual(t, note.Dirty, true, "Note dirty mismatch")
- testutils.AssertNotEqual(t, note.AddedOn, int64(0), "Note added_on mismatch")
-}
-
-func TestAddNote_ExistingBook_BodyFlag(t *testing.T) {
- // Set up
- ctx := testutils.InitEnv(t, "./tmp", "./testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- testutils.Setup3(t, ctx)
-
- // Execute
- testutils.RunDnoteCmd(t, ctx, binaryName, "add", "js", "-c", "foo")
-
- // Test
- db := ctx.DB
-
- var noteCount, bookCount int
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
-
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch")
- testutils.AssertEqualf(t, noteCount, 2, "note count mismatch")
-
- var n1, n2 core.Note
- testutils.MustScan(t, "getting n1",
- db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"), &n1.UUID, &n1.Body, &n1.AddedOn, &n1.Dirty)
- testutils.MustScan(t, "getting n2",
- db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes WHERE book_uuid = ? AND body = ?", "js-book-uuid", "foo"), &n2.UUID, &n2.Body, &n2.AddedOn, &n2.Dirty)
-
- var book core.Book
- testutils.MustScan(t, "getting book", db.QueryRow("SELECT dirty FROM books where label = ?", "js"), &book.Dirty)
-
- testutils.AssertEqual(t, book.Dirty, false, "Book dirty mismatch")
-
- testutils.AssertNotEqual(t, n1.UUID, "", "n1 should have UUID")
- testutils.AssertEqual(t, n1.Body, "Booleans have toString()", "n1 body mismatch")
- testutils.AssertEqual(t, n1.AddedOn, int64(1515199943), "n1 added_on mismatch")
- testutils.AssertEqual(t, n1.Dirty, false, "n1 dirty mismatch")
-
- testutils.AssertNotEqual(t, n2.UUID, "", "n2 should have UUID")
- testutils.AssertEqual(t, n2.Body, "foo", "n2 body mismatch")
- testutils.AssertEqual(t, n2.Dirty, true, "n2 dirty mismatch")
-}
-
-func TestEditNote_BodyFlag(t *testing.T) {
- // Set up
- ctx := testutils.InitEnv(t, "./tmp", "./testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- testutils.Setup4(t, ctx)
-
- // Execute
- testutils.RunDnoteCmd(t, ctx, binaryName, "edit", "2", "-c", "foo bar")
-
- // Test
- db := ctx.DB
-
- var noteCount, bookCount int
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
-
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch")
- testutils.AssertEqualf(t, noteCount, 2, "note count mismatch")
-
- var n1, n2 core.Note
- testutils.MustScan(t, "getting n1",
- db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes where book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"), &n1.UUID, &n1.Body, &n1.AddedOn, &n1.Dirty)
- testutils.MustScan(t, "getting n2",
- db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes where book_uuid = ? AND uuid = ?", "js-book-uuid", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f"), &n2.UUID, &n2.Body, &n2.AddedOn, &n2.Dirty)
-
- testutils.AssertEqual(t, n1.UUID, "43827b9a-c2b0-4c06-a290-97991c896653", "n1 should have UUID")
- testutils.AssertEqual(t, n1.Body, "Booleans have toString()", "n1 body mismatch")
- testutils.AssertEqual(t, n1.Dirty, false, "n1 dirty mismatch")
-
- testutils.AssertEqual(t, n2.UUID, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", "Note should have UUID")
- testutils.AssertEqual(t, n2.Body, "foo bar", "Note body mismatch")
- testutils.AssertEqual(t, n2.Dirty, true, "n2 dirty mismatch")
- testutils.AssertNotEqual(t, n2.EditedOn, 0, "Note edited_on mismatch")
-}
-
-func TestRemoveNote(t *testing.T) {
- // Set up
- ctx := testutils.InitEnv(t, "./tmp", "./testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- testutils.Setup2(t, ctx)
-
- // Execute
- testutils.WaitDnoteCmd(t, ctx, testutils.UserConfirm, binaryName, "remove", "js", "1")
-
- // Test
- db := ctx.DB
-
- var noteCount, bookCount, jsNoteCount, linuxNoteCount int
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting js notes", db.QueryRow("SELECT count(*) FROM notes WHERE book_uuid = ?", "js-book-uuid"), &jsNoteCount)
- testutils.MustScan(t, "counting linux notes", db.QueryRow("SELECT count(*) FROM notes WHERE book_uuid = ?", "linux-book-uuid"), &linuxNoteCount)
-
- testutils.AssertEqualf(t, bookCount, 2, "book count mismatch")
- testutils.AssertEqualf(t, noteCount, 3, "note count mismatch")
- testutils.AssertEqual(t, jsNoteCount, 2, "js book should have 2 notes")
- testutils.AssertEqual(t, linuxNoteCount, 1, "linux book book should have 1 note")
-
- var b1, b2 core.Book
- var n1, n2, n3 core.Note
- testutils.MustScan(t, "getting b1",
- db.QueryRow("SELECT label, deleted, usn FROM books WHERE uuid = ?", "js-book-uuid"),
- &b1.Label, &b1.Deleted, &b1.USN)
- testutils.MustScan(t, "getting b2",
- db.QueryRow("SELECT label, deleted, usn FROM books WHERE uuid = ?", "linux-book-uuid"),
- &b2.Label, &b2.Deleted, &b2.USN)
- testutils.MustScan(t, "getting n1",
- db.QueryRow("SELECT uuid, body, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f"),
- &n1.UUID, &n1.Body, &n1.AddedOn, &n1.Deleted, &n1.Dirty, &n1.USN)
- testutils.MustScan(t, "getting n2",
- db.QueryRow("SELECT uuid, body, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"),
- &n2.UUID, &n2.Body, &n2.AddedOn, &n2.Deleted, &n2.Dirty, &n2.USN)
- testutils.MustScan(t, "getting n3",
- db.QueryRow("SELECT uuid, body, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "linux-book-uuid", "3e065d55-6d47-42f2-a6bf-f5844130b2d2"),
- &n3.UUID, &n3.Body, &n3.AddedOn, &n3.Deleted, &n3.Dirty, &n3.USN)
-
- testutils.AssertEqual(t, b1.Label, "js", "b1 label mismatch")
- testutils.AssertEqual(t, b1.Deleted, false, "b1 deleted mismatch")
- testutils.AssertEqual(t, b1.Dirty, false, "b1 Dirty mismatch")
- testutils.AssertEqual(t, b1.USN, 111, "b1 usn mismatch")
-
- testutils.AssertEqual(t, b2.Label, "linux", "b2 label mismatch")
- testutils.AssertEqual(t, b2.Deleted, false, "b2 deleted mismatch")
- testutils.AssertEqual(t, b2.Dirty, false, "b2 Dirty mismatch")
- testutils.AssertEqual(t, b2.USN, 122, "b2 usn mismatch")
-
- testutils.AssertEqual(t, n1.UUID, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", "n1 should have UUID")
- testutils.AssertEqual(t, n1.Body, "", "n1 body mismatch")
- testutils.AssertEqual(t, n1.Deleted, true, "n1 deleted mismatch")
- testutils.AssertEqual(t, n1.Dirty, true, "n1 Dirty mismatch")
- testutils.AssertEqual(t, n1.USN, 11, "n1 usn mismatch")
-
- testutils.AssertEqual(t, n2.UUID, "43827b9a-c2b0-4c06-a290-97991c896653", "n2 should have UUID")
- testutils.AssertEqual(t, n2.Body, "n2 body", "n2 body mismatch")
- testutils.AssertEqual(t, n2.Deleted, false, "n2 deleted mismatch")
- testutils.AssertEqual(t, n2.Dirty, false, "n2 Dirty mismatch")
- testutils.AssertEqual(t, n2.USN, 12, "n2 usn mismatch")
-
- testutils.AssertEqual(t, n3.UUID, "3e065d55-6d47-42f2-a6bf-f5844130b2d2", "n3 should have UUID")
- testutils.AssertEqual(t, n3.Body, "n3 body", "n3 body mismatch")
- testutils.AssertEqual(t, n3.Deleted, false, "n3 deleted mismatch")
- testutils.AssertEqual(t, n3.Dirty, false, "n3 Dirty mismatch")
- testutils.AssertEqual(t, n3.USN, 13, "n3 usn mismatch")
-}
-
-func TestRemoveBook(t *testing.T) {
- // Set up
- ctx := testutils.InitEnv(t, "./tmp", "./testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- testutils.Setup2(t, ctx)
-
- // Execute
- testutils.WaitDnoteCmd(t, ctx, testutils.UserConfirm, binaryName, "remove", "-b", "js")
-
- // Test
- db := ctx.DB
-
- var noteCount, bookCount, jsNoteCount, linuxNoteCount int
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting js notes", db.QueryRow("SELECT count(*) FROM notes WHERE book_uuid = ?", "js-book-uuid"), &jsNoteCount)
- testutils.MustScan(t, "counting linux notes", db.QueryRow("SELECT count(*) FROM notes WHERE book_uuid = ?", "linux-book-uuid"), &linuxNoteCount)
-
- testutils.AssertEqualf(t, bookCount, 2, "book count mismatch")
- testutils.AssertEqualf(t, noteCount, 3, "note count mismatch")
- testutils.AssertEqual(t, jsNoteCount, 2, "js book should have 2 notes")
- testutils.AssertEqual(t, linuxNoteCount, 1, "linux book book should have 1 note")
-
- var b1, b2 core.Book
- var n1, n2, n3 core.Note
- testutils.MustScan(t, "getting b1",
- db.QueryRow("SELECT label, dirty, deleted, usn FROM books WHERE uuid = ?", "js-book-uuid"),
- &b1.Label, &b1.Dirty, &b1.Deleted, &b1.USN)
- testutils.MustScan(t, "getting b2",
- db.QueryRow("SELECT label, dirty, deleted, usn FROM books WHERE uuid = ?", "linux-book-uuid"),
- &b2.Label, &b2.Dirty, &b2.Deleted, &b2.USN)
- testutils.MustScan(t, "getting n1",
- db.QueryRow("SELECT uuid, body, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f"),
- &n1.UUID, &n1.Body, &n1.AddedOn, &n1.Deleted, &n1.Dirty, &n1.USN)
- testutils.MustScan(t, "getting n2",
- db.QueryRow("SELECT uuid, body, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"),
- &n2.UUID, &n2.Body, &n2.AddedOn, &n2.Deleted, &n2.Dirty, &n2.USN)
- testutils.MustScan(t, "getting n3",
- db.QueryRow("SELECT uuid, body, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "linux-book-uuid", "3e065d55-6d47-42f2-a6bf-f5844130b2d2"),
- &n3.UUID, &n3.Body, &n3.AddedOn, &n3.Deleted, &n3.Dirty, &n3.USN)
-
- testutils.AssertNotEqual(t, b1.Label, "js", "b1 label mismatch")
- testutils.AssertEqual(t, b1.Dirty, true, "b1 Dirty mismatch")
- testutils.AssertEqual(t, b1.Deleted, true, "b1 deleted mismatch")
- testutils.AssertEqual(t, b1.USN, 111, "b1 usn mismatch")
-
- testutils.AssertEqual(t, b2.Label, "linux", "b2 label mismatch")
- testutils.AssertEqual(t, b2.Dirty, false, "b2 Dirty mismatch")
- testutils.AssertEqual(t, b2.Deleted, false, "b2 deleted mismatch")
- testutils.AssertEqual(t, b2.USN, 122, "b2 usn mismatch")
-
- testutils.AssertEqual(t, n1.UUID, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", "n1 should have UUID")
- testutils.AssertEqual(t, n1.Body, "", "n1 body mismatch")
- testutils.AssertEqual(t, n1.Dirty, true, "n1 Dirty mismatch")
- testutils.AssertEqual(t, n1.Deleted, true, "n1 deleted mismatch")
- testutils.AssertEqual(t, n1.USN, 11, "n1 usn mismatch")
-
- testutils.AssertEqual(t, n2.UUID, "43827b9a-c2b0-4c06-a290-97991c896653", "n2 should have UUID")
- testutils.AssertEqual(t, n2.Body, "", "n2 body mismatch")
- testutils.AssertEqual(t, n2.Dirty, true, "n2 Dirty mismatch")
- testutils.AssertEqual(t, n2.Deleted, true, "n2 deleted mismatch")
- testutils.AssertEqual(t, n2.USN, 12, "n2 usn mismatch")
-
- testutils.AssertEqual(t, n3.UUID, "3e065d55-6d47-42f2-a6bf-f5844130b2d2", "n3 should have UUID")
- testutils.AssertEqual(t, n3.Body, "n3 body", "n3 body mismatch")
- testutils.AssertEqual(t, n3.Dirty, false, "n3 Dirty mismatch")
- testutils.AssertEqual(t, n3.Deleted, false, "n3 deleted mismatch")
- testutils.AssertEqual(t, n3.USN, 13, "n3 usn mismatch")
-}
diff --git a/cli/migrate/migrate_test.go b/cli/migrate/migrate_test.go
deleted file mode 100644
index a8e0122e..00000000
--- a/cli/migrate/migrate_test.go
+++ /dev/null
@@ -1,1115 +0,0 @@
-/* Copyright (C) 2019 Monomax Software Pty Ltd
- *
- * This file is part of Dnote CLI.
- *
- * Dnote CLI is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote CLI is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dnote CLI. If not, see .
- */
-
-package migrate
-
-import (
- "encoding/json"
- "fmt"
- "net/http"
- "net/http/httptest"
- "testing"
- "time"
-
- "github.com/dnote/actions"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/testutils"
- "github.com/dnote/dnote/cli/utils"
- "github.com/pkg/errors"
-)
-
-func TestExecute_bump_schema(t *testing.T) {
- testCases := []struct {
- schemaKey string
- }{
- {
- schemaKey: infra.SystemSchema,
- },
- {
- schemaKey: infra.SystemRemoteSchema,
- },
- }
-
- for _, tc := range testCases {
- func() {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
- testutils.MustExec(t, "inserting a schema", db, "INSERT INTO system (key, value) VALUES (?, ?)", tc.schemaKey, 8)
-
- m1 := migration{
- name: "noop",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- return nil
- },
- }
- m2 := migration{
- name: "noop",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- return nil
- },
- }
-
- // execute
- err := execute(ctx, m1, tc.schemaKey)
- if err != nil {
- t.Fatal(errors.Wrap(err, "failed to execute"))
- }
- err = execute(ctx, m2, tc.schemaKey)
- if err != nil {
- t.Fatal(errors.Wrap(err, "failed to execute"))
- }
-
- // test
- var schema int
- testutils.MustScan(t, "getting schema", db.QueryRow("SELECT value FROM system WHERE key = ?", tc.schemaKey), &schema)
- testutils.AssertEqual(t, schema, 10, "schema was not incremented properly")
- }()
- }
-}
-
-func TestRun_nonfresh(t *testing.T) {
- testCases := []struct {
- mode int
- schemaKey string
- }{
- {
- mode: LocalMode,
- schemaKey: infra.SystemSchema,
- },
- {
- mode: RemoteMode,
- schemaKey: infra.SystemRemoteSchema,
- },
- }
-
- for _, tc := range testCases {
- func() {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
- testutils.MustExec(t, "inserting a schema", db, "INSERT INTO system (key, value) VALUES (?, ?)", tc.schemaKey, 2)
- testutils.MustExec(t, "creating a temporary table for testing", db,
- "CREATE TABLE migrate_run_test ( name string )")
-
- sequence := []migration{
- migration{
- name: "v1",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- testutils.MustExec(t, "marking v1 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v1")
- return nil
- },
- },
- migration{
- name: "v2",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- testutils.MustExec(t, "marking v2 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v2")
- return nil
- },
- },
- migration{
- name: "v3",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- testutils.MustExec(t, "marking v3 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v3")
- return nil
- },
- },
- migration{
- name: "v4",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- testutils.MustExec(t, "marking v4 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v4")
- return nil
- },
- },
- }
-
- // execute
- err := Run(ctx, sequence, tc.mode)
- if err != nil {
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- // test
- var schema int
- testutils.MustScan(t, fmt.Sprintf("getting schema for %s", tc.schemaKey), db.QueryRow("SELECT value FROM system WHERE key = ?", tc.schemaKey), &schema)
- testutils.AssertEqual(t, schema, 4, fmt.Sprintf("schema was not updated for %s", tc.schemaKey))
-
- var testRunCount int
- testutils.MustScan(t, "counting test runs", db.QueryRow("SELECT count(*) FROM migrate_run_test"), &testRunCount)
- testutils.AssertEqual(t, testRunCount, 2, "test run count mismatch")
-
- var testRun1, testRun2 string
- testutils.MustScan(t, "finding test run 1", db.QueryRow("SELECT name FROM migrate_run_test WHERE name = ?", "v3"), &testRun1)
- testutils.MustScan(t, "finding test run 2", db.QueryRow("SELECT name FROM migrate_run_test WHERE name = ?", "v4"), &testRun2)
- }()
- }
-
-}
-
-func TestRun_fresh(t *testing.T) {
- testCases := []struct {
- mode int
- schemaKey string
- }{
- {
- mode: LocalMode,
- schemaKey: infra.SystemSchema,
- },
- {
- mode: RemoteMode,
- schemaKey: infra.SystemRemoteSchema,
- },
- }
-
- for _, tc := range testCases {
- func() {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
- testutils.MustExec(t, "creating a temporary table for testing", db,
- "CREATE TABLE migrate_run_test ( name string )")
-
- sequence := []migration{
- migration{
- name: "v1",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- testutils.MustExec(t, "marking v1 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v1")
- return nil
- },
- },
- migration{
- name: "v2",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- testutils.MustExec(t, "marking v2 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v2")
- return nil
- },
- },
- migration{
- name: "v3",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- testutils.MustExec(t, "marking v3 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v3")
- return nil
- },
- },
- }
-
- // execute
- err := Run(ctx, sequence, tc.mode)
- if err != nil {
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- // test
- var schema int
- testutils.MustScan(t, "getting schema", db.QueryRow("SELECT value FROM system WHERE key = ?", tc.schemaKey), &schema)
- testutils.AssertEqual(t, schema, 3, "schema was not updated")
-
- var testRunCount int
- testutils.MustScan(t, "counting test runs", db.QueryRow("SELECT count(*) FROM migrate_run_test"), &testRunCount)
- testutils.AssertEqual(t, testRunCount, 3, "test run count mismatch")
-
- var testRun1, testRun2, testRun3 string
- testutils.MustScan(t, "finding test run 1", db.QueryRow("SELECT name FROM migrate_run_test WHERE name = ?", "v1"), &testRun1)
- testutils.MustScan(t, "finding test run 2", db.QueryRow("SELECT name FROM migrate_run_test WHERE name = ?", "v2"), &testRun2)
- testutils.MustScan(t, "finding test run 2", db.QueryRow("SELECT name FROM migrate_run_test WHERE name = ?", "v3"), &testRun3)
- }()
- }
-}
-
-func TestRun_up_to_date(t *testing.T) {
- testCases := []struct {
- mode int
- schemaKey string
- }{
- {
- mode: LocalMode,
- schemaKey: infra.SystemSchema,
- },
- {
- mode: RemoteMode,
- schemaKey: infra.SystemRemoteSchema,
- },
- }
-
- for _, tc := range testCases {
- func() {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
- testutils.MustExec(t, "creating a temporary table for testing", db,
- "CREATE TABLE migrate_run_test ( name string )")
-
- testutils.MustExec(t, "inserting a schema", db, "INSERT INTO system (key, value) VALUES (?, ?)", tc.schemaKey, 3)
-
- sequence := []migration{
- migration{
- name: "v1",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- testutils.MustExec(t, "marking v1 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v1")
- return nil
- },
- },
- migration{
- name: "v2",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- testutils.MustExec(t, "marking v2 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v2")
- return nil
- },
- },
- migration{
- name: "v3",
- run: func(ctx infra.DnoteCtx, db *infra.DB) error {
- testutils.MustExec(t, "marking v3 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v3")
- return nil
- },
- },
- }
-
- // execute
- err := Run(ctx, sequence, tc.mode)
- if err != nil {
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- // test
- var schema int
- testutils.MustScan(t, "getting schema", db.QueryRow("SELECT value FROM system WHERE key = ?", tc.schemaKey), &schema)
- testutils.AssertEqual(t, schema, 3, "schema was not updated")
-
- var testRunCount int
- testutils.MustScan(t, "counting test runs", db.QueryRow("SELECT count(*) FROM migrate_run_test"), &testRunCount)
- testutils.AssertEqual(t, testRunCount, 0, "test run count mismatch")
- }()
- }
-}
-
-func TestLocalMigration1(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-1-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- data := testutils.MustMarshalJSON(t, actions.AddBookDataV1{BookName: "js"})
- a1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting action", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a1UUID, 1, "add_book", string(data), 1537829463)
-
- data = testutils.MustMarshalJSON(t, actions.EditNoteDataV1{NoteUUID: "note-1-uuid", FromBook: "js", ToBook: "", Content: "note 1"})
- a2UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting action", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a2UUID, 1, "edit_note", string(data), 1537829463)
-
- data = testutils.MustMarshalJSON(t, actions.EditNoteDataV1{NoteUUID: "note-2-uuid", FromBook: "js", ToBook: "", Content: "note 2"})
- a3UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting action", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a3UUID, 1, "edit_note", string(data), 1537829463)
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm1.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
- var actionCount int
- testutils.MustScan(t, "counting actions", db.QueryRow("SELECT count(*) FROM actions"), &actionCount)
- testutils.AssertEqual(t, actionCount, 3, "action count mismatch")
-
- var a1, a2, a3 actions.Action
- testutils.MustScan(t, "getting action 1", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a1UUID),
- &a1.Schema, &a1.Type, &a1.Data, &a1.Timestamp)
- testutils.MustScan(t, "getting action 2", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a2UUID),
- &a2.Schema, &a2.Type, &a2.Data, &a2.Timestamp)
- testutils.MustScan(t, "getting action 3", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a3UUID),
- &a3.Schema, &a3.Type, &a3.Data, &a3.Timestamp)
-
- var a1Data actions.AddBookDataV1
- var a2Data, a3Data actions.EditNoteDataV3
- testutils.MustUnmarshalJSON(t, a1.Data, &a1Data)
- testutils.MustUnmarshalJSON(t, a2.Data, &a2Data)
- testutils.MustUnmarshalJSON(t, a3.Data, &a3Data)
-
- testutils.AssertEqual(t, a1.Schema, 1, "a1 schema mismatch")
- testutils.AssertEqual(t, a1.Type, "add_book", "a1 type mismatch")
- testutils.AssertEqual(t, a1.Timestamp, int64(1537829463), "a1 timestamp mismatch")
- testutils.AssertEqual(t, a1Data.BookName, "js", "a1 data book_name mismatch")
-
- testutils.AssertEqual(t, a2.Schema, 3, "a2 schema mismatch")
- testutils.AssertEqual(t, a2.Type, "edit_note", "a2 type mismatch")
- testutils.AssertEqual(t, a2.Timestamp, int64(1537829463), "a2 timestamp mismatch")
- testutils.AssertEqual(t, a2Data.NoteUUID, "note-1-uuid", "a2 data note_uuid mismatch")
- testutils.AssertEqual(t, a2Data.BookName, (*string)(nil), "a2 data book_name mismatch")
- testutils.AssertEqual(t, *a2Data.Content, "note 1", "a2 data content mismatch")
- testutils.AssertEqual(t, *a2Data.Public, false, "a2 data public mismatch")
-
- testutils.AssertEqual(t, a3.Schema, 3, "a3 schema mismatch")
- testutils.AssertEqual(t, a3.Type, "edit_note", "a3 type mismatch")
- testutils.AssertEqual(t, a3.Timestamp, int64(1537829463), "a3 timestamp mismatch")
- testutils.AssertEqual(t, a3Data.NoteUUID, "note-2-uuid", "a3 data note_uuid mismatch")
- testutils.AssertEqual(t, a3Data.BookName, (*string)(nil), "a3 data book_name mismatch")
- testutils.AssertEqual(t, *a3Data.Content, "note 2", "a3 data content mismatch")
- testutils.AssertEqual(t, *a3Data.Public, false, "a3 data public mismatch")
-}
-
-func TestLocalMigration2(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-1-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- c1 := "note 1 - v1"
- c2 := "note 1 - v2"
- css := "css"
-
- b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting css book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "css")
-
- data := testutils.MustMarshalJSON(t, actions.AddNoteDataV2{NoteUUID: "note-1-uuid", BookName: "js", Content: "note 1", Public: false})
- a1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting action", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a1UUID, 2, "add_note", string(data), 1537829463)
-
- data = testutils.MustMarshalJSON(t, actions.EditNoteDataV2{NoteUUID: "note-1-uuid", FromBook: "js", ToBook: nil, Content: &c1, Public: nil})
- a2UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting action", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a2UUID, 2, "edit_note", string(data), 1537829463)
-
- data = testutils.MustMarshalJSON(t, actions.EditNoteDataV2{NoteUUID: "note-1-uuid", FromBook: "js", ToBook: &css, Content: &c2, Public: nil})
- a3UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting action", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a3UUID, 2, "edit_note", string(data), 1537829463)
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm2.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
- var actionCount int
- testutils.MustScan(t, "counting actions", db.QueryRow("SELECT count(*) FROM actions"), &actionCount)
- testutils.AssertEqual(t, actionCount, 3, "action count mismatch")
-
- var a1, a2, a3 actions.Action
- testutils.MustScan(t, "getting action 1", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a1UUID),
- &a1.Schema, &a1.Type, &a1.Data, &a1.Timestamp)
- testutils.MustScan(t, "getting action 2", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a2UUID),
- &a2.Schema, &a2.Type, &a2.Data, &a2.Timestamp)
- testutils.MustScan(t, "getting action 3", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a3UUID),
- &a3.Schema, &a3.Type, &a3.Data, &a3.Timestamp)
-
- var a1Data actions.AddNoteDataV2
- var a2Data, a3Data actions.EditNoteDataV3
- testutils.MustUnmarshalJSON(t, a1.Data, &a1Data)
- testutils.MustUnmarshalJSON(t, a2.Data, &a2Data)
- testutils.MustUnmarshalJSON(t, a3.Data, &a3Data)
-
- testutils.AssertEqual(t, a1.Schema, 2, "a1 schema mismatch")
- testutils.AssertEqual(t, a1.Type, "add_note", "a1 type mismatch")
- testutils.AssertEqual(t, a1.Timestamp, int64(1537829463), "a1 timestamp mismatch")
- testutils.AssertEqual(t, a1Data.NoteUUID, "note-1-uuid", "a1 data note_uuid mismatch")
- testutils.AssertEqual(t, a1Data.BookName, "js", "a1 data book_name mismatch")
- testutils.AssertEqual(t, a1Data.Public, false, "a1 data public mismatch")
-
- testutils.AssertEqual(t, a2.Schema, 3, "a2 schema mismatch")
- testutils.AssertEqual(t, a2.Type, "edit_note", "a2 type mismatch")
- testutils.AssertEqual(t, a2.Timestamp, int64(1537829463), "a2 timestamp mismatch")
- testutils.AssertEqual(t, a2Data.NoteUUID, "note-1-uuid", "a2 data note_uuid mismatch")
- testutils.AssertEqual(t, a2Data.BookName, (*string)(nil), "a2 data book_name mismatch")
- testutils.AssertEqual(t, *a2Data.Content, c1, "a2 data content mismatch")
- testutils.AssertEqual(t, a2Data.Public, (*bool)(nil), "a2 data public mismatch")
-
- testutils.AssertEqual(t, a3.Schema, 3, "a3 schema mismatch")
- testutils.AssertEqual(t, a3.Type, "edit_note", "a3 type mismatch")
- testutils.AssertEqual(t, a3.Timestamp, int64(1537829463), "a3 timestamp mismatch")
- testutils.AssertEqual(t, a3Data.NoteUUID, "note-1-uuid", "a3 data note_uuid mismatch")
- testutils.AssertEqual(t, *a3Data.BookName, "css", "a3 data book_name mismatch")
- testutils.AssertEqual(t, *a3Data.Content, c2, "a3 data content mismatch")
- testutils.AssertEqual(t, a3Data.Public, (*bool)(nil), "a3 data public mismatch")
-}
-
-func TestLocalMigration3(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-1-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- data := testutils.MustMarshalJSON(t, actions.AddNoteDataV2{NoteUUID: "note-1-uuid", BookName: "js", Content: "note 1", Public: false})
- a1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting action", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a1UUID, 2, "add_note", string(data), 1537829463)
-
- data = testutils.MustMarshalJSON(t, actions.RemoveNoteDataV1{NoteUUID: "note-1-uuid", BookName: "js"})
- a2UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting action", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a2UUID, 1, "remove_note", string(data), 1537829463)
-
- data = testutils.MustMarshalJSON(t, actions.RemoveNoteDataV1{NoteUUID: "note-2-uuid", BookName: "js"})
- a3UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting action", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a3UUID, 1, "remove_note", string(data), 1537829463)
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm3.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
- var actionCount int
- testutils.MustScan(t, "counting actions", db.QueryRow("SELECT count(*) FROM actions"), &actionCount)
- testutils.AssertEqual(t, actionCount, 3, "action count mismatch")
-
- var a1, a2, a3 actions.Action
- testutils.MustScan(t, "getting action 1", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a1UUID),
- &a1.Schema, &a1.Type, &a1.Data, &a1.Timestamp)
- testutils.MustScan(t, "getting action 2", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a2UUID),
- &a2.Schema, &a2.Type, &a2.Data, &a2.Timestamp)
- testutils.MustScan(t, "getting action 3", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a3UUID),
- &a3.Schema, &a3.Type, &a3.Data, &a3.Timestamp)
-
- var a1Data actions.AddNoteDataV2
- var a2Data, a3Data actions.RemoveNoteDataV2
- testutils.MustUnmarshalJSON(t, a1.Data, &a1Data)
- testutils.MustUnmarshalJSON(t, a2.Data, &a2Data)
- testutils.MustUnmarshalJSON(t, a3.Data, &a3Data)
-
- testutils.AssertEqual(t, a1.Schema, 2, "a1 schema mismatch")
- testutils.AssertEqual(t, a1.Type, "add_note", "a1 type mismatch")
- testutils.AssertEqual(t, a1.Timestamp, int64(1537829463), "a1 timestamp mismatch")
- testutils.AssertEqual(t, a1Data.NoteUUID, "note-1-uuid", "a1 data note_uuid mismatch")
- testutils.AssertEqual(t, a1Data.BookName, "js", "a1 data book_name mismatch")
- testutils.AssertEqual(t, a1Data.Content, "note 1", "a1 data content mismatch")
- testutils.AssertEqual(t, a1Data.Public, false, "a1 data public mismatch")
-
- testutils.AssertEqual(t, a2.Schema, 2, "a2 schema mismatch")
- testutils.AssertEqual(t, a2.Type, "remove_note", "a2 type mismatch")
- testutils.AssertEqual(t, a2.Timestamp, int64(1537829463), "a2 timestamp mismatch")
- testutils.AssertEqual(t, a2Data.NoteUUID, "note-1-uuid", "a2 data note_uuid mismatch")
-
- testutils.AssertEqual(t, a3.Schema, 2, "a3 schema mismatch")
- testutils.AssertEqual(t, a3.Type, "remove_note", "a3 type mismatch")
- testutils.AssertEqual(t, a3.Timestamp, int64(1537829463), "a3 timestamp mismatch")
- testutils.AssertEqual(t, a3Data.NoteUUID, "note-2-uuid", "a3 data note_uuid mismatch")
-}
-
-func TestLocalMigration4(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-1-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting css book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "css")
- n1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting css note", db, "INSERT INTO notes (uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?)", n1UUID, b1UUID, "n1 content", time.Now().UnixNano())
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm4.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
- var n1Dirty, b1Dirty bool
- var n1Deleted, b1Deleted bool
- var n1USN, b1USN int
- testutils.MustScan(t, "scanning the newly added dirty flag of n1", db.QueryRow("SELECT dirty, deleted, usn FROM notes WHERE uuid = ?", n1UUID), &n1Dirty, &n1Deleted, &n1USN)
- testutils.MustScan(t, "scanning the newly added dirty flag of b1", db.QueryRow("SELECT dirty, deleted, usn FROM books WHERE uuid = ?", b1UUID), &b1Dirty, &b1Deleted, &b1USN)
-
- testutils.AssertEqual(t, n1Dirty, false, "n1 dirty flag should be false by default")
- testutils.AssertEqual(t, b1Dirty, false, "b1 dirty flag should be false by default")
-
- testutils.AssertEqual(t, n1Deleted, false, "n1 deleted flag should be false by default")
- testutils.AssertEqual(t, b1Deleted, false, "b1 deleted flag should be false by default")
-
- testutils.AssertEqual(t, n1USN, 0, "n1 usn flag should be 0 by default")
- testutils.AssertEqual(t, b1USN, 0, "b1 usn flag should be 0 by default")
-}
-
-func TestLocalMigration5(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-5-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting css book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "css")
- b2UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting js book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "js")
-
- n1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting css note", db, "INSERT INTO notes (uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?)", n1UUID, b1UUID, "n1 content", time.Now().UnixNano())
- n2UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting css note", db, "INSERT INTO notes (uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?)", n2UUID, b1UUID, "n2 content", time.Now().UnixNano())
- n3UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting css note", db, "INSERT INTO notes (uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?)", n3UUID, b1UUID, "n3 content", time.Now().UnixNano())
-
- data := testutils.MustMarshalJSON(t, actions.AddBookDataV1{BookName: "js"})
- testutils.MustExec(t, "inserting a1", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", "a1-uuid", 1, "add_book", string(data), 1537829463)
-
- data = testutils.MustMarshalJSON(t, actions.AddNoteDataV2{NoteUUID: n1UUID, BookName: "css", Content: "n1 content", Public: false})
- testutils.MustExec(t, "inserting a2", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", "a2-uuid", 1, "add_note", string(data), 1537829463)
-
- updatedContent := "updated content"
- data = testutils.MustMarshalJSON(t, actions.EditNoteDataV3{NoteUUID: n2UUID, BookName: (*string)(nil), Content: &updatedContent, Public: (*bool)(nil)})
- testutils.MustExec(t, "inserting a3", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", "a3-uuid", 1, "edit_note", string(data), 1537829463)
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm5.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
- var b1Dirty, b2Dirty, n1Dirty, n2Dirty, n3Dirty bool
- testutils.MustScan(t, "scanning the newly added dirty flag of b1", db.QueryRow("SELECT dirty FROM books WHERE uuid = ?", b1UUID), &b1Dirty)
- testutils.MustScan(t, "scanning the newly added dirty flag of b2", db.QueryRow("SELECT dirty FROM books WHERE uuid = ?", b2UUID), &b2Dirty)
- testutils.MustScan(t, "scanning the newly added dirty flag of n1", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", n1UUID), &n1Dirty)
- testutils.MustScan(t, "scanning the newly added dirty flag of n2", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", n2UUID), &n2Dirty)
- testutils.MustScan(t, "scanning the newly added dirty flag of n3", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", n3UUID), &n3Dirty)
-
- testutils.AssertEqual(t, b1Dirty, false, "b1 dirty flag should be false by default")
- testutils.AssertEqual(t, b2Dirty, true, "b2 dirty flag should be false by default")
- testutils.AssertEqual(t, n1Dirty, true, "n1 dirty flag should be false by default")
- testutils.AssertEqual(t, n2Dirty, true, "n2 dirty flag should be false by default")
- testutils.AssertEqual(t, n3Dirty, false, "n3 dirty flag should be false by default")
-}
-
-func TestLocalMigration6(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-5-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- data := testutils.MustMarshalJSON(t, actions.AddBookDataV1{BookName: "js"})
- a1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting action", db,
- "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a1UUID, 1, "add_book", string(data), 1537829463)
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm5.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
- var count int
- err = db.QueryRow("SELECT name FROM sqlite_master WHERE type='table' AND name = ?;", "actions").Scan(&count)
- testutils.AssertEqual(t, count, 0, "actions table should have been deleted")
-}
-
-func TestLocalMigration7_trash(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-7-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting trash book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "trash")
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm7.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
- var b1Label string
- var b1Dirty bool
- testutils.MustScan(t, "scanning b1 label", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b1UUID), &b1Label, &b1Dirty)
- testutils.AssertEqual(t, b1Label, "trash (2)", "b1 label was not migrated")
- testutils.AssertEqual(t, b1Dirty, true, "b1 was not marked dirty")
-}
-
-func TestLocalMigration7_conflicts(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-7-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "conflicts")
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm7.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
- var b1Label string
- var b1Dirty bool
- testutils.MustScan(t, "scanning b1 label", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b1UUID), &b1Label, &b1Dirty)
- testutils.AssertEqual(t, b1Label, "conflicts (2)", "b1 label was not migrated")
- testutils.AssertEqual(t, b1Dirty, true, "b1 was not marked dirty")
-}
-
-func TestLocalMigration7_conflicts_dup(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-7-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "conflicts")
- b2UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "conflicts (2)")
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm7.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
- var b1Label, b2Label string
- var b1Dirty, b2Dirty bool
- testutils.MustScan(t, "scanning b1 label", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b1UUID), &b1Label, &b1Dirty)
- testutils.MustScan(t, "scanning b2 label", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b2UUID), &b2Label, &b2Dirty)
- testutils.AssertEqual(t, b1Label, "conflicts (3)", "b1 label was not migrated")
- testutils.AssertEqual(t, b2Label, "conflicts (2)", "b1 label was not migrated")
- testutils.AssertEqual(t, b1Dirty, true, "b1 was not marked dirty")
- testutils.AssertEqual(t, b2Dirty, false, "b2 should not have been marked dirty")
-}
-
-func TestLocalMigration8(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-8-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1")
-
- n1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting n1", db, `INSERT INTO notes
- (id, uuid, book_uuid, content, added_on, edited_on, public, dirty, usn, deleted) VALUES
- (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, 1, n1UUID, b1UUID, "n1 Body", 1, 2, true, true, 20, false)
- n2UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting n2", db, `INSERT INTO notes
- (id, uuid, book_uuid, content, added_on, edited_on, public, dirty, usn, deleted) VALUES
- (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, 2, n2UUID, b1UUID, "", 3, 4, false, true, 21, true)
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm8.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
- var n1BookUUID, n1Body string
- var n1AddedOn, n1EditedOn int64
- var n1USN int
- var n1Public, n1Dirty, n1Deleted bool
- testutils.MustScan(t, "scanning n1", db.QueryRow("SELECT book_uuid, body, added_on, edited_on, usn, public, dirty, deleted FROM notes WHERE uuid = ?", n1UUID), &n1BookUUID, &n1Body, &n1AddedOn, &n1EditedOn, &n1USN, &n1Public, &n1Dirty, &n1Deleted)
-
- var n2BookUUID, n2Body string
- var n2AddedOn, n2EditedOn int64
- var n2USN int
- var n2Public, n2Dirty, n2Deleted bool
- testutils.MustScan(t, "scanning n2", db.QueryRow("SELECT book_uuid, body, added_on, edited_on, usn, public, dirty, deleted FROM notes WHERE uuid = ?", n2UUID), &n2BookUUID, &n2Body, &n2AddedOn, &n2EditedOn, &n2USN, &n2Public, &n2Dirty, &n2Deleted)
-
- testutils.AssertEqual(t, n1BookUUID, b1UUID, "n1 BookUUID mismatch")
- testutils.AssertEqual(t, n1Body, "n1 Body", "n1 Body mismatch")
- testutils.AssertEqual(t, n1AddedOn, int64(1), "n1 AddedOn mismatch")
- testutils.AssertEqual(t, n1EditedOn, int64(2), "n1 EditedOn mismatch")
- testutils.AssertEqual(t, n1USN, 20, "n1 USN mismatch")
- testutils.AssertEqual(t, n1Public, true, "n1 Public mismatch")
- testutils.AssertEqual(t, n1Dirty, true, "n1 Dirty mismatch")
- testutils.AssertEqual(t, n1Deleted, false, "n1 Deleted mismatch")
-
- testutils.AssertEqual(t, n2BookUUID, b1UUID, "n2 BookUUID mismatch")
- testutils.AssertEqual(t, n2Body, "", "n2 Body mismatch")
- testutils.AssertEqual(t, n2AddedOn, int64(3), "n2 AddedOn mismatch")
- testutils.AssertEqual(t, n2EditedOn, int64(4), "n2 EditedOn mismatch")
- testutils.AssertEqual(t, n2USN, 21, "n2 USN mismatch")
- testutils.AssertEqual(t, n2Public, false, "n2 Public mismatch")
- testutils.AssertEqual(t, n2Dirty, true, "n2 Dirty mismatch")
- testutils.AssertEqual(t, n2Deleted, true, "n2 Deleted mismatch")
-}
-
-func TestLocalMigration9(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-9-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1")
-
- n1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting n1", db, `INSERT INTO notes
- (uuid, book_uuid, body, added_on, edited_on, public, dirty, usn, deleted) VALUES
- (?, ?, ?, ?, ?, ?, ?, ?, ?)`, n1UUID, b1UUID, "n1 Body", 1, 2, true, true, 20, false)
- n2UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting n2", db, `INSERT INTO notes
- (uuid, book_uuid, body, added_on, edited_on, public, dirty, usn, deleted) VALUES
- (?, ?, ?, ?, ?, ?, ?, ?, ?)`, n2UUID, b1UUID, "n2 Body", 3, 4, false, true, 21, false)
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm9.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
-
- // assert that note_fts was populated with correct values
- var noteFtsCount int
- testutils.MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts;"), ¬eFtsCount)
- testutils.AssertEqual(t, noteFtsCount, 2, "noteFtsCount mismatch")
-
- var resCount int
- testutils.MustScan(t, "counting result", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "n1"), &resCount)
- testutils.AssertEqual(t, resCount, 1, "noteFtsCount mismatch")
-}
-
-func TestLocalMigration10(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-10-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "123")
- b2UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 2", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "123 javascript")
- b3UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 3", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b3UUID, "foo")
- b4UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 4", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b4UUID, "+123")
- b5UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 5", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b5UUID, "0123")
- b6UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 6", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b6UUID, "javascript 123")
- b7UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 7", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b7UUID, "123 (1)")
- b8UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 8", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b8UUID, "5")
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm10.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
-
- // assert that note_fts was populated with correct values
- var b1Label, b2Label, b3Label, b4Label, b5Label, b6Label, b7Label, b8Label string
- var b1Dirty, b2Dirty, b3Dirty, b4Dirty, b5Dirty, b6Dirty, b7Dirty, b8Dirty bool
-
- testutils.MustScan(t, "getting b1", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b1UUID), &b1Label, &b1Dirty)
- testutils.MustScan(t, "getting b2", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b2UUID), &b2Label, &b2Dirty)
- testutils.MustScan(t, "getting b3", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b3UUID), &b3Label, &b3Dirty)
- testutils.MustScan(t, "getting b4", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b4UUID), &b4Label, &b4Dirty)
- testutils.MustScan(t, "getting b5", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b5UUID), &b5Label, &b5Dirty)
- testutils.MustScan(t, "getting b6", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b6UUID), &b6Label, &b6Dirty)
- testutils.MustScan(t, "getting b7", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b7UUID), &b7Label, &b7Dirty)
- testutils.MustScan(t, "getting b8", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b8UUID), &b8Label, &b8Dirty)
-
- testutils.AssertEqual(t, b1Label, "123 (2)", "b1Label mismatch")
- testutils.AssertEqual(t, b1Dirty, true, "b1Dirty mismatch")
- testutils.AssertEqual(t, b2Label, "123 javascript", "b2Label mismatch")
- testutils.AssertEqual(t, b2Dirty, false, "b2Dirty mismatch")
- testutils.AssertEqual(t, b3Label, "foo", "b3Label mismatch")
- testutils.AssertEqual(t, b3Dirty, false, "b3Dirty mismatch")
- testutils.AssertEqual(t, b4Label, "+123", "b4Label mismatch")
- testutils.AssertEqual(t, b4Dirty, false, "b4Dirty mismatch")
- testutils.AssertEqual(t, b5Label, "0123 (1)", "b5Label mismatch")
- testutils.AssertEqual(t, b5Dirty, true, "b5Dirty mismatch")
- testutils.AssertEqual(t, b6Label, "javascript 123", "b6Label mismatch")
- testutils.AssertEqual(t, b6Dirty, false, "b6Dirty mismatch")
- testutils.AssertEqual(t, b7Label, "123 (1)", "b7Label mismatch")
- testutils.AssertEqual(t, b7Dirty, false, "b7Dirty mismatch")
- testutils.AssertEqual(t, b8Label, "5 (1)", "b8Label mismatch")
- testutils.AssertEqual(t, b8Dirty, true, "b8Dirty mismatch")
-}
-
-func TestLocalMigration11(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-11-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "foo")
- b2UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 2", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "bar baz")
- b3UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 3", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b3UUID, "quz qux")
- b4UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 4", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b4UUID, "quz_qux")
- b5UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 5", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b5UUID, "foo bar baz quz 123")
- b6UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 6", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b6UUID, "foo_bar baz")
- b7UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 7", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b7UUID, "cool ideas")
- b8UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 8", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b8UUID, "cool_ideas")
- b9UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book 9", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b9UUID, "cool_ideas_2")
-
- // Execute
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = lm11.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // Test
- var bookCount int
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqual(t, bookCount, 9, "bookCount mismatch")
-
- // assert that note_fts was populated with correct values
- var b1Label, b2Label, b3Label, b4Label, b5Label, b6Label, b7Label, b8Label, b9Label string
- var b1Dirty, b2Dirty, b3Dirty, b4Dirty, b5Dirty, b6Dirty, b7Dirty, b8Dirty, b9Dirty bool
-
- testutils.MustScan(t, "getting b1", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b1UUID), &b1Label, &b1Dirty)
- testutils.MustScan(t, "getting b2", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b2UUID), &b2Label, &b2Dirty)
- testutils.MustScan(t, "getting b3", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b3UUID), &b3Label, &b3Dirty)
- testutils.MustScan(t, "getting b4", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b4UUID), &b4Label, &b4Dirty)
- testutils.MustScan(t, "getting b5", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b5UUID), &b5Label, &b5Dirty)
- testutils.MustScan(t, "getting b6", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b6UUID), &b6Label, &b6Dirty)
- testutils.MustScan(t, "getting b7", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b7UUID), &b7Label, &b7Dirty)
- testutils.MustScan(t, "getting b8", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b8UUID), &b8Label, &b8Dirty)
- testutils.MustScan(t, "getting b9", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b9UUID), &b9Label, &b9Dirty)
-
- testutils.AssertEqual(t, b1Label, "foo", "b1Label mismatch")
- testutils.AssertEqual(t, b1Dirty, false, "b1Dirty mismatch")
- testutils.AssertEqual(t, b2Label, "bar_baz", "b2Label mismatch")
- testutils.AssertEqual(t, b2Dirty, true, "b2Dirty mismatch")
- testutils.AssertEqual(t, b3Label, "quz_qux_2", "b3Label mismatch")
- testutils.AssertEqual(t, b3Dirty, true, "b3Dirty mismatch")
- testutils.AssertEqual(t, b4Label, "quz_qux", "b4Label mismatch")
- testutils.AssertEqual(t, b4Dirty, false, "b4Dirty mismatch")
- testutils.AssertEqual(t, b5Label, "foo_bar_baz_quz_123", "b5Label mismatch")
- testutils.AssertEqual(t, b5Dirty, true, "b5Dirty mismatch")
- testutils.AssertEqual(t, b6Label, "foo_bar_baz", "b6Label mismatch")
- testutils.AssertEqual(t, b6Dirty, true, "b6Dirty mismatch")
- testutils.AssertEqual(t, b7Label, "cool_ideas_3", "b7Label mismatch")
- testutils.AssertEqual(t, b7Dirty, true, "b7Dirty mismatch")
- testutils.AssertEqual(t, b8Label, "cool_ideas", "b8Label mismatch")
- testutils.AssertEqual(t, b8Dirty, false, "b8Dirty mismatch")
- testutils.AssertEqual(t, b9Label, "cool_ideas_2", "b9Label mismatch")
- testutils.AssertEqual(t, b9Dirty, false, "b9Dirty mismatch")
-}
-
-func TestRemoteMigration1(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/remote-1-pre-schema.sql", false)
- testutils.Login(t, &ctx)
- defer testutils.TeardownEnv(ctx)
-
- JSBookUUID := "existing-js-book-uuid"
- CSSBookUUID := "existing-css-book-uuid"
- linuxBookUUID := "existing-linux-book-uuid"
- newJSBookUUID := "new-js-book-uuid"
- newCSSBookUUID := "new-css-book-uuid"
-
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.URL.String() == "/v1/books" {
- res := []struct {
- UUID string `json:"uuid"`
- Label string `json:"label"`
- }{
- {
- UUID: newJSBookUUID,
- Label: "js",
- },
- {
- UUID: newCSSBookUUID,
- Label: "css",
- },
- // book that only exists on the server. client must ignore.
- {
- UUID: "golang-book-uuid",
- Label: "golang",
- },
- }
-
- if err := json.NewEncoder(w).Encode(res); err != nil {
- t.Fatal(errors.Wrap(err, "encoding response"))
- }
- }
- }))
- defer server.Close()
-
- ctx.APIEndpoint = server.URL
-
- db := ctx.DB
-
- testutils.MustExec(t, "inserting js book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", JSBookUUID, "js")
- testutils.MustExec(t, "inserting css book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", CSSBookUUID, "css")
- testutils.MustExec(t, "inserting linux book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", linuxBookUUID, "linux")
- testutils.MustExec(t, "inserting sessionKey", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemSessionKey, "someSessionKey")
- testutils.MustExec(t, "inserting sessionKeyExpiry", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemSessionKeyExpiry, time.Now().Add(24*time.Hour).Unix())
-
- tx, err := db.Begin()
- if err != nil {
- t.Fatal(errors.Wrap(err, "beginning a transaction"))
- }
-
- err = rm1.run(ctx, tx)
- if err != nil {
- tx.Rollback()
- t.Fatal(errors.Wrap(err, "failed to run"))
- }
-
- tx.Commit()
-
- // test
- var postJSBookUUID, postCSSBookUUID, postLinuxBookUUID string
- testutils.MustScan(t, "getting js book uuid", db.QueryRow("SELECT uuid FROM books WHERE label = ?", "js"), &postJSBookUUID)
- testutils.MustScan(t, "getting css book uuid", db.QueryRow("SELECT uuid FROM books WHERE label = ?", "css"), &postCSSBookUUID)
- testutils.MustScan(t, "getting linux book uuid", db.QueryRow("SELECT uuid FROM books WHERE label = ?", "linux"), &postLinuxBookUUID)
-
- testutils.AssertEqual(t, postJSBookUUID, newJSBookUUID, "js book uuid was not updated correctly")
- testutils.AssertEqual(t, postCSSBookUUID, newCSSBookUUID, "css book uuid was not updated correctly")
- testutils.AssertEqual(t, postLinuxBookUUID, linuxBookUUID, "linux book uuid changed")
-}
diff --git a/cli/testutils/fixtures/schema.sql b/cli/testutils/fixtures/schema.sql
deleted file mode 100644
index a9679e45..00000000
--- a/cli/testutils/fixtures/schema.sql
+++ /dev/null
@@ -1,50 +0,0 @@
-CREATE TABLE books
- (
- uuid text PRIMARY KEY,
- label text NOT NULL
- , dirty bool DEFAULT false, usn int DEFAULT 0 NOT NULL, deleted bool DEFAULT false);
-CREATE TABLE system
- (
- key string NOT NULL,
- value text NOT NULL
- );
-CREATE UNIQUE INDEX idx_books_label ON books(label);
-CREATE UNIQUE INDEX idx_books_uuid ON books(uuid);
-CREATE TABLE IF NOT EXISTS "notes"
- (
- uuid text NOT NULL,
- book_uuid text NOT NULL,
- body text NOT NULL,
- added_on integer NOT NULL,
- edited_on integer DEFAULT 0,
- public bool DEFAULT false,
- dirty bool DEFAULT false,
- usn int DEFAULT 0 NOT NULL,
- deleted bool DEFAULT false
- );
-CREATE VIRTUAL TABLE note_fts USING fts5(content=notes, body, tokenize="porter unicode61 categories 'L* N* Co Ps Pe'")
-/* note_fts(body) */;
-CREATE TABLE IF NOT EXISTS 'note_fts_data'(id INTEGER PRIMARY KEY, block BLOB);
-CREATE TABLE IF NOT EXISTS 'note_fts_idx'(segid, term, pgno, PRIMARY KEY(segid, term)) WITHOUT ROWID;
-CREATE TABLE IF NOT EXISTS 'note_fts_docsize'(id INTEGER PRIMARY KEY, sz BLOB);
-CREATE TABLE IF NOT EXISTS 'note_fts_config'(k PRIMARY KEY, v) WITHOUT ROWID;
-CREATE TRIGGER notes_after_insert AFTER INSERT ON notes BEGIN
- INSERT INTO note_fts(rowid, body) VALUES (new.rowid, new.body);
- END;
-CREATE TRIGGER notes_after_delete AFTER DELETE ON notes BEGIN
- INSERT INTO note_fts(note_fts, rowid, body) VALUES ('delete', old.rowid, old.body);
- END;
-CREATE TRIGGER notes_after_update AFTER UPDATE ON notes BEGIN
- INSERT INTO note_fts(note_fts, rowid, body) VALUES ('delete', old.rowid, old.body);
- INSERT INTO note_fts(rowid, body) VALUES (new.rowid, new.body);
- END;
-CREATE TABLE actions
- (
- uuid text PRIMARY KEY,
- schema integer NOT NULL,
- type text NOT NULL,
- data text NOT NULL,
- timestamp integer NOT NULL
- );
-CREATE UNIQUE INDEX idx_notes_uuid ON notes(uuid);
-CREATE INDEX idx_notes_book_uuid ON notes(book_uuid);
diff --git a/cli/testutils/main.go b/cli/testutils/main.go
deleted file mode 100644
index 15a59674..00000000
--- a/cli/testutils/main.go
+++ /dev/null
@@ -1,363 +0,0 @@
-/* Copyright (C) 2019 Monomax Software Pty Ltd
- *
- * This file is part of Dnote CLI.
- *
- * Dnote CLI is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote CLI is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dnote CLI. If not, see .
- */
-
-// Package testutils provides utilities used in tests
-package testutils
-
-import (
- "bytes"
- "database/sql"
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "os/exec"
- "path/filepath"
- "reflect"
- "strings"
- "testing"
- "time"
-
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/utils"
- "github.com/pkg/errors"
-)
-
-// InitEnv sets up a test env and returns a new dnote context
-func InitEnv(t *testing.T, dnotehomePath string, fixturePath string, migrated bool) infra.DnoteCtx {
- os.Setenv("DNOTE_HOME_DIR", dnotehomePath)
- ctx, err := infra.NewCtx("", "")
- if err != nil {
- t.Fatal(errors.Wrap(err, "getting new ctx"))
- }
-
- // set up directory
- if err := os.MkdirAll(ctx.DnoteDir, 0755); err != nil {
- t.Fatal(err)
- }
-
- // set up db
- b := ReadFileAbs(fixturePath)
- setupSQL := string(b)
-
- db := ctx.DB
- if _, err := db.Exec(setupSQL); err != nil {
- t.Fatal(errors.Wrap(err, "running schema sql"))
- }
-
- if migrated {
- // mark migrations as done. When adding new migrations, bump the numbers here.
- if _, err := db.Exec("INSERT INTO system (key, value) VALUES (? , ?);", infra.SystemSchema, 11); err != nil {
- t.Fatal(errors.Wrap(err, "inserting schema"))
- }
-
- if _, err := db.Exec("INSERT INTO system (key, value) VALUES (? , ?);", infra.SystemRemoteSchema, 1); err != nil {
- t.Fatal(errors.Wrap(err, "inserting remote schema"))
- }
- }
-
- return ctx
-}
-
-// Login simulates a logged in user by inserting credentials in the local database
-func Login(t *testing.T, ctx *infra.DnoteCtx) {
- db := ctx.DB
-
- MustExec(t, "inserting sessionKey", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemSessionKey, "someSessionKey")
- MustExec(t, "inserting sessionKeyExpiry", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemSessionKeyExpiry, time.Now().Add(24*time.Hour).Unix())
- MustExec(t, "inserting cipherKey", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemCipherKey, "QUVTMjU2S2V5LTMyQ2hhcmFjdGVyczEyMzQ1Njc4OTA=")
-
- ctx.SessionKey = "someSessionKey"
- ctx.SessionKeyExpiry = time.Now().Add(24 * time.Hour).Unix()
- ctx.CipherKey = []byte("AES256Key-32Characters1234567890")
-}
-
-// TeardownEnv cleans up the test env represented by the given context
-func TeardownEnv(ctx infra.DnoteCtx) {
- ctx.DB.Close()
-
- if err := os.RemoveAll(ctx.DnoteDir); err != nil {
- panic(err)
- }
-}
-
-// CopyFixture writes the content of the given fixture to the filename inside the dnote dir
-func CopyFixture(ctx infra.DnoteCtx, fixturePath string, filename string) {
- fp, err := filepath.Abs(fixturePath)
- if err != nil {
- panic(err)
- }
- dp, err := filepath.Abs(filepath.Join(ctx.DnoteDir, filename))
- if err != nil {
- panic(err)
- }
-
- err = utils.CopyFile(fp, dp)
- if err != nil {
- panic(err)
- }
-}
-
-// WriteFile writes a file with the given content and filename inside the dnote dir
-func WriteFile(ctx infra.DnoteCtx, content []byte, filename string) {
- dp, err := filepath.Abs(filepath.Join(ctx.DnoteDir, filename))
- if err != nil {
- panic(err)
- }
-
- if err := ioutil.WriteFile(dp, content, 0644); err != nil {
- panic(err)
- }
-}
-
-// ReadFile reads the content of the file with the given name in dnote dir
-func ReadFile(ctx infra.DnoteCtx, filename string) []byte {
- path := filepath.Join(ctx.DnoteDir, filename)
-
- b, err := ioutil.ReadFile(path)
- if err != nil {
- panic(err)
- }
-
- return b
-}
-
-// ReadFileAbs reads the content of the file with the given file path by resolving
-// it as an absolute path
-func ReadFileAbs(relpath string) []byte {
- fp, err := filepath.Abs(relpath)
- if err != nil {
- panic(err)
- }
-
- b, err := ioutil.ReadFile(fp)
- if err != nil {
- panic(err)
- }
-
- return b
-}
-
-func checkEqual(a interface{}, b interface{}, message string) (bool, string) {
- if a == b {
- return true, ""
- }
-
- var m string
- if len(message) == 0 {
- m = fmt.Sprintf("%v != %v", a, b)
- } else {
- m = message
- }
- errorMessage := fmt.Sprintf("%s.\n==== Actual ====\n%+v\n=============\n==== Expected ====\n%+v\n=================", m, a, b)
-
- return false, errorMessage
-}
-
-// AssertEqual errors a test if the actual does not match the expected
-func AssertEqual(t *testing.T, a interface{}, b interface{}, message string) {
- ok, m := checkEqual(a, b, message)
- if !ok {
- t.Error(m)
- }
-}
-
-// AssertEqualf fails a test if the actual does not match the expected
-func AssertEqualf(t *testing.T, a interface{}, b interface{}, message string) {
- ok, m := checkEqual(a, b, message)
- if !ok {
- t.Fatal(m)
- }
-}
-
-// AssertNotEqual fails a test if the actual matches the expected
-func AssertNotEqual(t *testing.T, a interface{}, b interface{}, message string) {
- if a != b {
- return
- }
- if len(message) == 0 {
- message = fmt.Sprintf("%v == %v", a, b)
- }
- t.Errorf("%s. Actual: %+v. Expected: %+v.", message, a, b)
-}
-
-// AssertDeepEqual fails a test if the actual does not deeply equal the expected
-func AssertDeepEqual(t *testing.T, a interface{}, b interface{}, message string) {
- if reflect.DeepEqual(a, b) {
- return
- }
-
- if len(message) == 0 {
- message = fmt.Sprintf("%v != %v", a, b)
- }
- t.Errorf("%s.\nActual: %+v.\nExpected: %+v.", message, a, b)
-}
-
-// ReadJSON reads JSON fixture to the struct at the destination address
-func ReadJSON(path string, destination interface{}) {
- var dat []byte
- dat, err := ioutil.ReadFile(path)
- if err != nil {
- panic(errors.Wrap(err, "Failed to load fixture payload"))
- }
- if err := json.Unmarshal(dat, destination); err != nil {
- panic(errors.Wrap(err, "Failed to get event"))
- }
-}
-
-// IsEqualJSON deeply compares two JSON byte slices
-func IsEqualJSON(s1, s2 []byte) (bool, error) {
- var o1 interface{}
- var o2 interface{}
-
- if err := json.Unmarshal(s1, &o1); err != nil {
- return false, errors.Wrap(err, "unmarshalling first JSON")
- }
- if err := json.Unmarshal(s2, &o2); err != nil {
- return false, errors.Wrap(err, "unmarshalling second JSON")
- }
-
- return reflect.DeepEqual(o1, o2), nil
-}
-
-// MustExec executes the given SQL query and fails a test if an error occurs
-func MustExec(t *testing.T, message string, db *infra.DB, query string, args ...interface{}) sql.Result {
- result, err := db.Exec(query, args...)
- if err != nil {
- t.Fatal(errors.Wrap(errors.Wrap(err, "executing sql"), message))
- }
-
- return result
-}
-
-// MustScan scans the given row and fails a test in case of any errors
-func MustScan(t *testing.T, message string, row *sql.Row, args ...interface{}) {
- err := row.Scan(args...)
- if err != nil {
- t.Fatal(errors.Wrap(errors.Wrap(err, "scanning a row"), message))
- }
-}
-
-// NewDnoteCmd returns a new Dnote command and a pointer to stderr
-func NewDnoteCmd(ctx infra.DnoteCtx, binaryName string, arg ...string) (*exec.Cmd, *bytes.Buffer, *bytes.Buffer, error) {
- var stderr, stdout bytes.Buffer
-
- binaryPath, err := filepath.Abs(binaryName)
- if err != nil {
- return &exec.Cmd{}, &stderr, &stdout, errors.Wrap(err, "getting the absolute path to the test binary")
- }
-
- cmd := exec.Command(binaryPath, arg...)
- cmd.Env = []string{fmt.Sprintf("DNOTE_DIR=%s", ctx.DnoteDir), fmt.Sprintf("DNOTE_HOME_DIR=%s", ctx.HomeDir)}
- cmd.Stderr = &stderr
- cmd.Stdout = &stdout
-
- return cmd, &stderr, &stdout, nil
-}
-
-// RunDnoteCmd runs a dnote command
-func RunDnoteCmd(t *testing.T, ctx infra.DnoteCtx, binaryName string, arg ...string) {
- t.Logf("running: %s %s", binaryName, strings.Join(arg, " "))
-
- cmd, stderr, stdout, err := NewDnoteCmd(ctx, binaryName, arg...)
- if err != nil {
- t.Logf("\n%s", stdout)
- t.Fatal(errors.Wrap(err, "getting command").Error())
- }
-
- cmd.Env = append(cmd.Env, "DNOTE_DEBUG=1")
-
- if err := cmd.Run(); err != nil {
- t.Logf("\n%s", stdout)
- t.Fatal(errors.Wrapf(err, "running command %s", stderr.String()))
- }
-
- // Print stdout if and only if test fails later
- t.Logf("\n%s", stdout)
-}
-
-// WaitDnoteCmd runs a dnote command and waits until the command is exited
-func WaitDnoteCmd(t *testing.T, ctx infra.DnoteCtx, runFunc func(io.WriteCloser) error, binaryName string, arg ...string) {
- t.Logf("running: %s %s", binaryName, strings.Join(arg, " "))
-
- cmd, stderr, stdout, err := NewDnoteCmd(ctx, binaryName, arg...)
- if err != nil {
- t.Logf("\n%s", stdout)
- t.Fatal(errors.Wrap(err, "getting command").Error())
- }
-
- stdin, err := cmd.StdinPipe()
- if err != nil {
- t.Logf("\n%s", stdout)
- t.Fatal(errors.Wrap(err, "getting stdin %s"))
- }
- defer stdin.Close()
-
- // Start the program
- err = cmd.Start()
- if err != nil {
- t.Logf("\n%s", stdout)
- t.Fatal(errors.Wrap(err, "starting command"))
- }
-
- err = runFunc(stdin)
- if err != nil {
- t.Logf("\n%s", stdout)
- t.Fatal(errors.Wrap(err, "running with stdin"))
- }
-
- err = cmd.Wait()
- if err != nil {
- t.Logf("\n%s", stdout)
- t.Fatal(errors.Wrapf(err, "running command %s", stderr.String()))
- }
-
- // Print stdout if and only if test fails later
- t.Logf("\n%s", stdout)
-}
-
-// UserConfirm simulates confirmation from the user by writing to stdin
-func UserConfirm(stdin io.WriteCloser) error {
- // confirm
- if _, err := io.WriteString(stdin, "y\n"); err != nil {
- return errors.Wrap(err, "indicating confirmation in stdin")
- }
-
- return nil
-}
-
-// MustMarshalJSON marshalls the given interface into JSON.
-// If there is any error, it fails the test.
-func MustMarshalJSON(t *testing.T, v interface{}) []byte {
- b, err := json.Marshal(v)
- if err != nil {
- t.Fatalf("%s: marshalling data", t.Name())
- }
-
- return b
-}
-
-// MustUnmarshalJSON marshalls the given interface into JSON.
-// If there is any error, it fails the test.
-func MustUnmarshalJSON(t *testing.T, data []byte, v interface{}) {
- err := json.Unmarshal(data, v)
- if err != nil {
- t.Fatalf("%s: unmarshalling data", t.Name())
- }
-}
diff --git a/cli/testutils/setup.go b/cli/testutils/setup.go
deleted file mode 100644
index 73b21d8a..00000000
--- a/cli/testutils/setup.go
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright (C) 2019 Monomax Software Pty Ltd
- *
- * This file is part of Dnote CLI.
- *
- * Dnote CLI is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dnote CLI is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dnote CLI. If not, see .
- */
-
-package testutils
-
-import (
- "github.com/dnote/dnote/cli/infra"
- "testing"
-)
-
-// Setup1 sets up a dnote env #1
-// dnote4.json
-func Setup1(t *testing.T, ctx infra.DnoteCtx) {
- db := ctx.DB
-
- b1UUID := "js-book-uuid"
- b2UUID := "linux-book-uuid"
-
- MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "js")
- MustExec(t, "setting up book 2", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "linux")
-
- MustExec(t, "setting up note 1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?)", "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
-}
-
-// Setup2 sets up a dnote env #2
-// dnote3.json
-func Setup2(t *testing.T, ctx infra.DnoteCtx) {
- db := ctx.DB
-
- b1UUID := "js-book-uuid"
- b2UUID := "linux-book-uuid"
-
- MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label, usn) VALUES (?, ?, ?)", b1UUID, "js", 111)
- MustExec(t, "setting up book 2", db, "INSERT INTO books (uuid, label, usn) VALUES (?, ?, ?)", b2UUID, "linux", 122)
-
- MustExec(t, "setting up note 1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn) VALUES (?, ?, ?, ?, ?)", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", b1UUID, "n1 body", 1515199951, 11)
- MustExec(t, "setting up note 2", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn) VALUES (?, ?, ?, ?, ?)", "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "n2 body", 1515199943, 12)
- MustExec(t, "setting up note 3", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn) VALUES (?, ?, ?, ?, ?)", "3e065d55-6d47-42f2-a6bf-f5844130b2d2", b2UUID, "n3 body", 1515199961, 13)
-}
-
-// Setup3 sets up a dnote env #1
-// dnote1.json
-func Setup3(t *testing.T, ctx infra.DnoteCtx) {
- db := ctx.DB
-
- b1UUID := "js-book-uuid"
-
- MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "js")
-
- MustExec(t, "setting up note 1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?)", "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
-}
-
-// Setup4 sets up a dnote env #1
-// dnote2.json
-func Setup4(t *testing.T, ctx infra.DnoteCtx) {
- db := ctx.DB
-
- b1UUID := "js-book-uuid"
-
- MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "js")
-
- MustExec(t, "setting up note 1", db, "INSERT INTO notes (rowid, uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?, ?)", 1, "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
- MustExec(t, "setting up note 2", db, "INSERT INTO notes (rowid, uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?, ?)", 2, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", b1UUID, "Date object implements mathematical comparisons", 1515199951)
-}
diff --git a/pkg/assert/assert.go b/pkg/assert/assert.go
new file mode 100644
index 00000000..7ef193e0
--- /dev/null
+++ b/pkg/assert/assert.go
@@ -0,0 +1,123 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+// Package assert provides functions to assert a condition in tests
+package assert
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "reflect"
+ "testing"
+
+ "github.com/pkg/errors"
+)
+
+func checkEqual(a interface{}, b interface{}, message string) (bool, string) {
+ if a == b {
+ return true, ""
+ }
+
+ var m string
+ if len(message) == 0 {
+ m = fmt.Sprintf("%v != %v", a, b)
+ } else {
+ m = message
+ }
+ errorMessage := fmt.Sprintf("%s.\n==== Actual ====\n%+v\n=============\n==== Expected ====\n%+v\n=================", m, a, b)
+
+ return false, errorMessage
+}
+
+// Equal errors a test if the actual does not match the expected
+func Equal(t *testing.T, a interface{}, b interface{}, message string) {
+ ok, m := checkEqual(a, b, message)
+ if !ok {
+ t.Error(m)
+ }
+}
+
+// Equalf fails a test if the actual does not match the expected
+func Equalf(t *testing.T, a interface{}, b interface{}, message string) {
+ ok, m := checkEqual(a, b, message)
+ if !ok {
+ t.Fatal(m)
+ }
+}
+
+// NotEqual fails a test if the actual matches the expected
+func NotEqual(t *testing.T, a interface{}, b interface{}, message string) {
+ if a != b {
+ return
+ }
+ if len(message) == 0 {
+ message = fmt.Sprintf("%v == %v", a, b)
+ }
+ t.Errorf("%s. Actual: %+v. Expected: %+v.", message, a, b)
+}
+
+// DeepEqual fails a test if the actual does not deeply equal the expected
+func DeepEqual(t *testing.T, a interface{}, b interface{}, message string) {
+ if reflect.DeepEqual(a, b) {
+ return
+ }
+
+ if len(message) == 0 {
+ message = fmt.Sprintf("%v != %v", a, b)
+ }
+ t.Errorf("%s.\nActual: %+v.\nExpected: %+v.", message, a, b)
+}
+
+// EqualJSON asserts that two JSON strings are equal
+func EqualJSON(t *testing.T, a, b, message string) {
+ var o1 interface{}
+ var o2 interface{}
+
+ err := json.Unmarshal([]byte(a), &o1)
+ if err != nil {
+ panic(fmt.Errorf("Error mashalling string 1 :: %s", err.Error()))
+ }
+ err = json.Unmarshal([]byte(b), &o2)
+ if err != nil {
+ panic(fmt.Errorf("Error mashalling string 2 :: %s", err.Error()))
+ }
+
+ if reflect.DeepEqual(o1, o2) {
+ return
+ }
+
+ if len(message) == 0 {
+ message = fmt.Sprintf("%v != %v", a, b)
+ }
+ t.Errorf("%s.\nActual: %+v.\nExpected: %+v.", message, a, b)
+}
+
+// StatusCodeEquals asserts that the reponse's status code is equal to the
+// expected
+func StatusCodeEquals(t *testing.T, res *http.Response, expected int, message string) {
+ if res.StatusCode != expected {
+ body, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "reading body"))
+ }
+
+ t.Errorf("status code mismatch. %s: got %v want %v. Message was: '%s'", message, res.StatusCode, expected, string(body))
+ }
+}
diff --git a/cli/.gitignore b/pkg/cli/.gitignore
similarity index 100%
rename from cli/.gitignore
rename to pkg/cli/.gitignore
diff --git a/cli/COMMANDS.md b/pkg/cli/COMMANDS.md
similarity index 100%
rename from cli/COMMANDS.md
rename to pkg/cli/COMMANDS.md
diff --git a/cli/Gopkg.lock b/pkg/cli/Gopkg.lock
similarity index 87%
rename from cli/Gopkg.lock
rename to pkg/cli/Gopkg.lock
index 9db5f4ed..9598c01b 100644
--- a/cli/Gopkg.lock
+++ b/pkg/cli/Gopkg.lock
@@ -17,6 +17,14 @@
revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4"
version = "v1.7.0"
+[[projects]]
+ branch = "endpoint-186"
+ digest = "1:b56e65cab256427453f4454af3e7be2c1c544b52332772dbf7e6992aa7fdf599"
+ name = "github.com/dnote/dnote"
+ packages = ["pkg/assert"]
+ pruneopts = ""
+ revision = "54646c6bf85fba5efb8b4de67c9fed19cdbe0d97"
+
[[projects]]
branch = "master"
digest = "1:fe99ddb68e996f2f9f7995e9765bc283ceef12dbe30de17922900c1cfa9dfc09"
@@ -81,6 +89,14 @@
revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3"
version = "v1.2.0"
+[[projects]]
+ digest = "1:3962f553b77bf6c03fc07cd687a22dd3b00fe11aa14d31194f5505f5bb65cdc8"
+ name = "github.com/sergi/go-diff"
+ packages = ["diffmatchpatch"]
+ pruneopts = ""
+ revision = "1744e2970ca51c86172c8190fadad617561ed6e7"
+ version = "v1.0.0"
+
[[projects]]
digest = "1:78715f4ed019d19795e67eed1dc63f525461d925616b1ed02b72582c01362440"
name = "github.com/spf13/cobra"
@@ -134,10 +150,12 @@
input-imports = [
"github.com/dnote/actions",
"github.com/dnote/color",
+ "github.com/dnote/dnote/pkg/assert",
"github.com/google/go-github/github",
"github.com/mattn/go-sqlite3",
"github.com/pkg/errors",
"github.com/satori/go.uuid",
+ "github.com/sergi/go-diff/diffmatchpatch",
"github.com/spf13/cobra",
"golang.org/x/crypto/hkdf",
"golang.org/x/crypto/pbkdf2",
diff --git a/cli/Gopkg.toml b/pkg/cli/Gopkg.toml
similarity index 100%
rename from cli/Gopkg.toml
rename to pkg/cli/Gopkg.toml
diff --git a/cli/Makefile b/pkg/cli/Makefile
similarity index 100%
rename from cli/Makefile
rename to pkg/cli/Makefile
diff --git a/cli/README.md b/pkg/cli/README.md
similarity index 100%
rename from cli/README.md
rename to pkg/cli/README.md
diff --git a/cli/client/client.go b/pkg/cli/client/client.go
similarity index 91%
rename from cli/client/client.go
rename to pkg/cli/client/client.go
index 8697adc5..d3f81a76 100644
--- a/cli/client/client.go
+++ b/pkg/cli/client/client.go
@@ -30,8 +30,8 @@ import (
"strings"
"time"
- "github.com/dnote/dnote/cli/crypt"
- "github.com/dnote/dnote/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/crypt"
"github.com/pkg/errors"
)
@@ -43,7 +43,7 @@ type requestOptions struct {
HTTPClient *http.Client
}
-func getReq(ctx infra.DnoteCtx, path, method, body string) (*http.Request, error) {
+func getReq(ctx context.DnoteCtx, path, method, body string) (*http.Request, error) {
endpoint := fmt.Sprintf("%s%s", ctx.APIEndpoint, path)
req, err := http.NewRequest(method, endpoint, strings.NewReader(body))
if err != nil {
@@ -77,7 +77,7 @@ func checkRespErr(res *http.Response) error {
}
// doReq does a http request to the given path in the api endpoint
-func doReq(ctx infra.DnoteCtx, method, path, body string, options *requestOptions) (*http.Response, error) {
+func doReq(ctx context.DnoteCtx, method, path, body string, options *requestOptions) (*http.Response, error) {
req, err := getReq(ctx, path, method, body)
if err != nil {
return nil, errors.Wrap(err, "getting request")
@@ -104,7 +104,7 @@ func doReq(ctx infra.DnoteCtx, method, path, body string, options *requestOption
// doAuthorizedReq does a http request to the given path in the api endpoint as a user,
// with the appropriate headers. The given path should include the preceding slash.
-func doAuthorizedReq(ctx infra.DnoteCtx, method, path, body string, options *requestOptions) (*http.Response, error) {
+func doAuthorizedReq(ctx context.DnoteCtx, method, path, body string, options *requestOptions) (*http.Response, error) {
if ctx.SessionKey == "" {
return nil, errors.New("no session key found")
}
@@ -120,7 +120,7 @@ type GetSyncStateResp struct {
}
// GetSyncState gets the sync state response from the server
-func GetSyncState(ctx infra.DnoteCtx) (GetSyncStateResp, error) {
+func GetSyncState(ctx context.DnoteCtx) (GetSyncStateResp, error) {
var ret GetSyncStateResp
res, err := doAuthorizedReq(ctx, "GET", "/v1/sync/state", "", nil)
@@ -184,7 +184,7 @@ type GetSyncFragmentResp struct {
}
// GetSyncFragment gets a sync fragment response from the server
-func GetSyncFragment(ctx infra.DnoteCtx, afterUSN int) (GetSyncFragmentResp, error) {
+func GetSyncFragment(ctx context.DnoteCtx, afterUSN int) (GetSyncFragmentResp, error) {
v := url.Values{}
v.Set("after_usn", strconv.Itoa(afterUSN))
queryStr := v.Encode()
@@ -226,7 +226,7 @@ type CreateBookResp struct {
}
// CreateBook creates a new book in the server
-func CreateBook(ctx infra.DnoteCtx, label string) (CreateBookResp, error) {
+func CreateBook(ctx context.DnoteCtx, label string) (CreateBookResp, error) {
encLabel, err := crypt.AesGcmEncrypt(ctx.CipherKey, []byte(label))
if err != nil {
return CreateBookResp{}, errors.Wrap(err, "encrypting the label")
@@ -263,7 +263,7 @@ type UpdateBookResp struct {
}
// UpdateBook updates a book in the server
-func UpdateBook(ctx infra.DnoteCtx, label, uuid string) (UpdateBookResp, error) {
+func UpdateBook(ctx context.DnoteCtx, label, uuid string) (UpdateBookResp, error) {
encName, err := crypt.AesGcmEncrypt(ctx.CipherKey, []byte(label))
if err != nil {
return UpdateBookResp{}, errors.Wrap(err, "encrypting the content")
@@ -298,7 +298,7 @@ type DeleteBookResp struct {
}
// DeleteBook deletes a book in the server
-func DeleteBook(ctx infra.DnoteCtx, uuid string) (DeleteBookResp, error) {
+func DeleteBook(ctx context.DnoteCtx, uuid string) (DeleteBookResp, error) {
endpoint := fmt.Sprintf("/v1/books/%s", uuid)
res, err := doAuthorizedReq(ctx, "DELETE", endpoint, "", nil)
if err != nil {
@@ -347,7 +347,7 @@ type RespNote struct {
}
// CreateNote creates a note in the server
-func CreateNote(ctx infra.DnoteCtx, bookUUID, content string) (CreateNoteResp, error) {
+func CreateNote(ctx context.DnoteCtx, bookUUID, content string) (CreateNoteResp, error) {
encBody, err := crypt.AesGcmEncrypt(ctx.CipherKey, []byte(content))
if err != nil {
return CreateNoteResp{}, errors.Wrap(err, "encrypting the content")
@@ -388,7 +388,7 @@ type UpdateNoteResp struct {
}
// UpdateNote updates a note in the server
-func UpdateNote(ctx infra.DnoteCtx, uuid, bookUUID, content string, public bool) (UpdateNoteResp, error) {
+func UpdateNote(ctx context.DnoteCtx, uuid, bookUUID, content string, public bool) (UpdateNoteResp, error) {
encBody, err := crypt.AesGcmEncrypt(ctx.CipherKey, []byte(content))
if err != nil {
return UpdateNoteResp{}, errors.Wrap(err, "encrypting the content")
@@ -425,7 +425,7 @@ type DeleteNoteResp struct {
}
// DeleteNote removes a note in the server
-func DeleteNote(ctx infra.DnoteCtx, uuid string) (DeleteNoteResp, error) {
+func DeleteNote(ctx context.DnoteCtx, uuid string) (DeleteNoteResp, error) {
endpoint := fmt.Sprintf("/v1/notes/%s", uuid)
res, err := doAuthorizedReq(ctx, "DELETE", endpoint, "", nil)
if err != nil {
@@ -447,7 +447,7 @@ type GetBooksResp []struct {
}
// GetBooks gets books from the server
-func GetBooks(ctx infra.DnoteCtx, sessionKey string) (GetBooksResp, error) {
+func GetBooks(ctx context.DnoteCtx, sessionKey string) (GetBooksResp, error) {
res, err := doAuthorizedReq(ctx, "GET", "/v1/books", "", nil)
if err != nil {
return GetBooksResp{}, errors.Wrap(err, "making http request")
@@ -467,7 +467,7 @@ type PresigninResponse struct {
}
// GetPresignin gets presignin credentials
-func GetPresignin(ctx infra.DnoteCtx, email string) (PresigninResponse, error) {
+func GetPresignin(ctx context.DnoteCtx, email string) (PresigninResponse, error) {
res, err := doReq(ctx, "GET", fmt.Sprintf("/v1/presignin?email=%s", email), "", nil)
if err != nil {
return PresigninResponse{}, errors.Wrap(err, "making http request")
@@ -495,7 +495,7 @@ type SigninResponse struct {
}
// Signin requests a session token
-func Signin(ctx infra.DnoteCtx, email, authKey string) (SigninResponse, error) {
+func Signin(ctx context.DnoteCtx, email, authKey string) (SigninResponse, error) {
payload := SigninPayload{
Email: email,
AuthKey: authKey,
@@ -522,7 +522,7 @@ func Signin(ctx infra.DnoteCtx, email, authKey string) (SigninResponse, error) {
}
// Signout deletes a user session on the server side
-func Signout(ctx infra.DnoteCtx, sessionKey string) error {
+func Signout(ctx context.DnoteCtx, sessionKey string) error {
hc := http.Client{
// No need to follow redirect
CheckRedirect: func(req *http.Request, via []*http.Request) error {
diff --git a/cli/cmd/add/add.go b/pkg/cli/cmd/add/add.go
similarity index 81%
rename from cli/cmd/add/add.go
rename to pkg/cli/cmd/add/add.go
index 3eaaff69..11be9ec0 100644
--- a/cli/cmd/add/add.go
+++ b/pkg/cli/cmd/add/add.go
@@ -23,10 +23,14 @@ import (
"strings"
"time"
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
- "github.com/dnote/dnote/cli/utils"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/log"
+ "github.com/dnote/dnote/pkg/cli/output"
+ "github.com/dnote/dnote/pkg/cli/ui"
+ "github.com/dnote/dnote/pkg/cli/upgrade"
+ "github.com/dnote/dnote/pkg/cli/utils"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -51,7 +55,7 @@ func preRun(cmd *cobra.Command, args []string) error {
}
// NewCmd returns a new add command
-func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
+func NewCmd(ctx context.DnoteCtx) *cobra.Command {
cmd := &cobra.Command{
Use: "add ",
Short: "Add a new note",
@@ -102,7 +106,7 @@ func validateBookName(name string) error {
return nil
}
-func newRun(ctx infra.DnoteCtx) core.RunEFunc {
+func newRun(ctx context.DnoteCtx) infra.RunEFunc {
return func(cmd *cobra.Command, args []string) error {
bookName := args[0]
@@ -111,8 +115,8 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
}
if content == "" {
- fpath := core.GetDnoteTmpContentPath(ctx)
- err := core.GetEditorInput(ctx, fpath, &content)
+ fpath := ui.GetTmpContentPath(ctx)
+ err := ui.GetEditorInput(ctx, fpath, &content)
if err != nil {
return errors.Wrap(err, "Failed to get editor input")
}
@@ -130,14 +134,15 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
log.Successf("added to %s\n", bookName)
- info, err := core.GetNoteInfo(ctx, noteRowID)
+ db := ctx.DB
+ info, err := database.GetNoteInfo(db, noteRowID)
if err != nil {
return err
}
- core.PrintNoteInfo(info)
+ output.NoteInfo(info)
- if err := core.CheckUpdate(ctx); err != nil {
+ if err := upgrade.Check(ctx); err != nil {
log.Error(errors.Wrap(err, "automatically checking updates").Error())
}
@@ -145,7 +150,7 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
}
}
-func writeNote(ctx infra.DnoteCtx, bookLabel string, content string, ts int64) (string, error) {
+func writeNote(ctx context.DnoteCtx, bookLabel string, content string, ts int64) (string, error) {
tx, err := ctx.DB.Begin()
if err != nil {
return "", errors.Wrap(err, "beginning a transaction")
@@ -156,7 +161,7 @@ func writeNote(ctx infra.DnoteCtx, bookLabel string, content string, ts int64) (
if err == sql.ErrNoRows {
bookUUID = utils.GenerateUUID()
- b := core.NewBook(bookUUID, bookLabel, 0, false, true)
+ b := database.NewBook(bookUUID, bookLabel, 0, false, true)
err = b.Insert(tx)
if err != nil {
tx.Rollback()
@@ -167,7 +172,7 @@ func writeNote(ctx infra.DnoteCtx, bookLabel string, content string, ts int64) (
}
noteUUID := utils.GenerateUUID()
- n := core.NewNote(noteUUID, bookUUID, content, ts, 0, 0, false, false, true)
+ n := database.NewNote(noteUUID, bookUUID, content, ts, 0, 0, false, false, true)
err = n.Insert(tx)
if err != nil {
diff --git a/cli/cmd/add/add_test.go b/pkg/cli/cmd/add/add_test.go
similarity index 92%
rename from cli/cmd/add/add_test.go
rename to pkg/cli/cmd/add/add_test.go
index 0b93401b..e1129a74 100644
--- a/cli/cmd/add/add_test.go
+++ b/pkg/cli/cmd/add/add_test.go
@@ -22,7 +22,7 @@ import (
"fmt"
"testing"
- "github.com/dnote/dnote/cli/testutils"
+ "github.com/dnote/dnote/pkg/assert"
)
func TestValidateBookName(t *testing.T) {
@@ -101,6 +101,6 @@ func TestValidateBookName(t *testing.T) {
for _, tc := range testCases {
actual := validateBookName(tc.input)
- testutils.AssertEqual(t, actual, tc.expected, fmt.Sprintf("result does not match for the input '%s'", tc.input))
+ assert.Equal(t, actual, tc.expected, fmt.Sprintf("result does not match for the input '%s'", tc.input))
}
}
diff --git a/cli/cmd/cat/cat.go b/pkg/cli/cmd/cat/cat.go
similarity index 82%
rename from cli/cmd/cat/cat.go
rename to pkg/cli/cmd/cat/cat.go
index 253fa87f..b9209083 100644
--- a/cli/cmd/cat/cat.go
+++ b/pkg/cli/cmd/cat/cat.go
@@ -19,9 +19,11 @@
package cat
import (
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/log"
+ "github.com/dnote/dnote/pkg/cli/output"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -45,7 +47,7 @@ func preRun(cmd *cobra.Command, args []string) error {
}
// NewCmd returns a new cat command
-func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
+func NewCmd(ctx context.DnoteCtx) *cobra.Command {
cmd := &cobra.Command{
Use: "cat ",
Aliases: []string{"c"},
@@ -60,7 +62,7 @@ func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
}
// NewRun returns a new run function
-func NewRun(ctx infra.DnoteCtx) core.RunEFunc {
+func NewRun(ctx context.DnoteCtx) infra.RunEFunc {
return func(cmd *cobra.Command, args []string) error {
var noteRowID string
@@ -72,12 +74,13 @@ func NewRun(ctx infra.DnoteCtx) core.RunEFunc {
noteRowID = args[0]
}
- info, err := core.GetNoteInfo(ctx, noteRowID)
+ db := ctx.DB
+ info, err := database.GetNoteInfo(db, noteRowID)
if err != nil {
return err
}
- core.PrintNoteInfo(info)
+ output.NoteInfo(info)
return nil
}
diff --git a/cli/cmd/edit/edit.go b/pkg/cli/cmd/edit/edit.go
similarity index 88%
rename from cli/cmd/edit/edit.go
rename to pkg/cli/cmd/edit/edit.go
index 71b7216f..4ec1daa9 100644
--- a/cli/cmd/edit/edit.go
+++ b/pkg/cli/cmd/edit/edit.go
@@ -24,9 +24,10 @@ import (
"io/ioutil"
"time"
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/log"
+ "github.com/dnote/dnote/pkg/cli/ui"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -41,7 +42,7 @@ var example = `
dnote edit 3 -c "new content"`
// NewCmd returns a new edit command
-func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
+func NewCmd(ctx context.DnoteCtx) *cobra.Command {
cmd := &cobra.Command{
Use: "edit",
Short: "Edit a note",
@@ -65,7 +66,7 @@ func preRun(cmd *cobra.Command, args []string) error {
return nil
}
-func newRun(ctx infra.DnoteCtx) core.RunEFunc {
+func newRun(ctx context.DnoteCtx) infra.RunEFunc {
return func(cmd *cobra.Command, args []string) error {
db := ctx.DB
@@ -88,14 +89,14 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
}
if newContent == "" {
- fpath := core.GetDnoteTmpContentPath(ctx)
+ fpath := ui.GetTmpContentPath(ctx)
e := ioutil.WriteFile(fpath, []byte(oldContent), 0644)
if e != nil {
return errors.Wrap(e, "preparing tmp content file")
}
- e = core.GetEditorInput(ctx, fpath, &newContent)
+ e = ui.GetEditorInput(ctx, fpath, &newContent)
if e != nil {
return errors.Wrap(err, "getting editor input")
}
@@ -106,7 +107,7 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
}
ts := time.Now().UnixNano()
- newContent = core.SanitizeContent(newContent)
+ newContent = ui.SanitizeContent(newContent)
tx, err := db.Begin()
if err != nil {
diff --git a/cli/cmd/find/find.go b/pkg/cli/cmd/find/find.go
similarity index 93%
rename from cli/cmd/find/find.go
rename to pkg/cli/cmd/find/find.go
index b03fc4cc..f0ec061f 100644
--- a/cli/cmd/find/find.go
+++ b/pkg/cli/cmd/find/find.go
@@ -23,9 +23,9 @@ import (
"fmt"
"strings"
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/log"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -52,7 +52,7 @@ func preRun(cmd *cobra.Command, args []string) error {
}
// NewCmd returns a new remove command
-func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
+func NewCmd(ctx context.DnoteCtx) *cobra.Command {
cmd := &cobra.Command{
Use: "find",
Short: "Find notes by keywords",
@@ -130,7 +130,7 @@ func escapePhrase(s string) (string, error) {
return b.String(), nil
}
-func doQuery(ctx infra.DnoteCtx, query, bookName string) (*sql.Rows, error) {
+func doQuery(ctx context.DnoteCtx, query, bookName string) (*sql.Rows, error) {
db := ctx.DB
sql := `SELECT
@@ -153,7 +153,7 @@ func doQuery(ctx infra.DnoteCtx, query, bookName string) (*sql.Rows, error) {
return rows, err
}
-func newRun(ctx infra.DnoteCtx) core.RunEFunc {
+func newRun(ctx context.DnoteCtx) infra.RunEFunc {
return func(cmd *cobra.Command, args []string) error {
phrase, err := escapePhrase(args[0])
if err != nil {
diff --git a/cli/cmd/find/lexer.go b/pkg/cli/cmd/find/lexer.go
similarity index 100%
rename from cli/cmd/find/lexer.go
rename to pkg/cli/cmd/find/lexer.go
diff --git a/cli/cmd/find/lexer_test.go b/pkg/cli/cmd/find/lexer_test.go
similarity index 94%
rename from cli/cmd/find/lexer_test.go
rename to pkg/cli/cmd/find/lexer_test.go
index 55118695..db5ae7d9 100644
--- a/cli/cmd/find/lexer_test.go
+++ b/pkg/cli/cmd/find/lexer_test.go
@@ -22,7 +22,7 @@ import (
"fmt"
"testing"
- "github.com/dnote/dnote/cli/testutils"
+ "github.com/dnote/dnote/pkg/assert"
)
func TestScanToken(t *testing.T) {
@@ -117,8 +117,8 @@ func TestScanToken(t *testing.T) {
t.Run(fmt.Sprintf("test case %d", tcIdx), func(t *testing.T) {
tok, nextIdx := scanToken(tc.idx, tc.input)
- testutils.AssertEqual(t, nextIdx, tc.retIdx, "retIdx mismatch")
- testutils.AssertDeepEqual(t, tok, tc.retTok, "retTok mismatch")
+ assert.Equal(t, nextIdx, tc.retIdx, "retIdx mismatch")
+ assert.DeepEqual(t, tok, tc.retTok, "retTok mismatch")
})
}
}
@@ -225,7 +225,7 @@ func TestTokenize(t *testing.T) {
t.Run(fmt.Sprintf("test case %d", tcIdx), func(t *testing.T) {
tokens := tokenize(tc.input)
- testutils.AssertDeepEqual(t, tokens, tc.tokens, "tokens mismatch")
+ assert.DeepEqual(t, tokens, tc.tokens, "tokens mismatch")
})
}
}
diff --git a/cli/cmd/login/login.go b/pkg/cli/cmd/login/login.go
similarity index 74%
rename from cli/cmd/login/login.go
rename to pkg/cli/cmd/login/login.go
index e2ffdf95..2a9dce39 100644
--- a/cli/cmd/login/login.go
+++ b/pkg/cli/cmd/login/login.go
@@ -22,12 +22,14 @@ import (
"encoding/base64"
"strconv"
- "github.com/dnote/dnote/cli/client"
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/crypt"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
- "github.com/dnote/dnote/cli/utils"
+ "github.com/dnote/dnote/pkg/cli/client"
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/crypt"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/log"
+ "github.com/dnote/dnote/pkg/cli/ui"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -36,7 +38,7 @@ var example = `
dnote login`
// NewCmd returns a new login command
-func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
+func NewCmd(ctx context.DnoteCtx) *cobra.Command {
cmd := &cobra.Command{
Use: "login",
Short: "Login to dnote server",
@@ -48,7 +50,7 @@ func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
}
// Do dervies credentials on the client side and requests a session token from the server
-func Do(ctx infra.DnoteCtx, email, password string) error {
+func Do(ctx context.DnoteCtx, email, password string) error {
presigninResp, err := client.GetPresignin(ctx, email)
if err != nil {
return errors.Wrap(err, "getting presiginin")
@@ -78,13 +80,13 @@ func Do(ctx infra.DnoteCtx, email, password string) error {
return errors.Wrap(err, "beginning a transaction")
}
- if err := core.UpsertSystem(tx, infra.SystemCipherKey, cipherKeyDecB64); err != nil {
+ if err := database.UpsertSystem(tx, consts.SystemCipherKey, cipherKeyDecB64); err != nil {
return errors.Wrap(err, "saving enc key")
}
- if err := core.UpsertSystem(tx, infra.SystemSessionKey, signinResp.Key); err != nil {
+ if err := database.UpsertSystem(tx, consts.SystemSessionKey, signinResp.Key); err != nil {
return errors.Wrap(err, "saving session key")
}
- if err := core.UpsertSystem(tx, infra.SystemSessionKeyExpiry, strconv.FormatInt(signinResp.ExpiresAt, 10)); err != nil {
+ if err := database.UpsertSystem(tx, consts.SystemSessionKeyExpiry, strconv.FormatInt(signinResp.ExpiresAt, 10)); err != nil {
return errors.Wrap(err, "saving session key")
}
@@ -93,17 +95,17 @@ func Do(ctx infra.DnoteCtx, email, password string) error {
return nil
}
-func newRun(ctx infra.DnoteCtx) core.RunEFunc {
+func newRun(ctx context.DnoteCtx) infra.RunEFunc {
return func(cmd *cobra.Command, args []string) error {
var email, password string
- if err := utils.PromptInput("email", &email); err != nil {
+ if err := ui.PromptInput("email", &email); err != nil {
return errors.Wrap(err, "getting email input")
}
if email == "" {
return errors.New("Email is empty")
}
- if err := utils.PromptPassword("password", &password); err != nil {
+ if err := ui.PromptPassword("password", &password); err != nil {
return errors.Wrap(err, "getting password input")
}
if password == "" {
diff --git a/cli/cmd/logout/logout.go b/pkg/cli/cmd/logout/logout.go
similarity index 74%
rename from cli/cmd/logout/logout.go
rename to pkg/cli/cmd/logout/logout.go
index 4f8536dc..1f3888e6 100644
--- a/cli/cmd/logout/logout.go
+++ b/pkg/cli/cmd/logout/logout.go
@@ -21,10 +21,12 @@ package logout
import (
"database/sql"
- "github.com/dnote/dnote/cli/client"
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
+ "github.com/dnote/dnote/pkg/cli/client"
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/log"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -36,7 +38,7 @@ var example = `
dnote logout`
// NewCmd returns a new logout command
-func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
+func NewCmd(ctx context.DnoteCtx) *cobra.Command {
cmd := &cobra.Command{
Use: "logout",
Short: "Logout from the server",
@@ -48,7 +50,7 @@ func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
}
// Do performs logout
-func Do(ctx infra.DnoteCtx) error {
+func Do(ctx context.DnoteCtx) error {
db := ctx.DB
tx, err := db.Begin()
if err != nil {
@@ -56,7 +58,7 @@ func Do(ctx infra.DnoteCtx) error {
}
var key string
- err = core.GetSystem(tx, infra.SystemSessionKey, &key)
+ err = database.GetSystem(tx, consts.SystemSessionKey, &key)
if errors.Cause(err) == sql.ErrNoRows {
return ErrNotLoggedIn
} else if err != nil {
@@ -68,13 +70,13 @@ func Do(ctx infra.DnoteCtx) error {
return errors.Wrap(err, "requesting logout")
}
- if err := core.DeleteSystem(tx, infra.SystemCipherKey); err != nil {
+ if err := database.DeleteSystem(tx, consts.SystemCipherKey); err != nil {
return errors.Wrap(err, "deleting enc key")
}
- if err := core.DeleteSystem(tx, infra.SystemSessionKey); err != nil {
+ if err := database.DeleteSystem(tx, consts.SystemSessionKey); err != nil {
return errors.Wrap(err, "deleting session key")
}
- if err := core.DeleteSystem(tx, infra.SystemSessionKeyExpiry); err != nil {
+ if err := database.DeleteSystem(tx, consts.SystemSessionKeyExpiry); err != nil {
return errors.Wrap(err, "deleting session key expiry")
}
@@ -83,7 +85,7 @@ func Do(ctx infra.DnoteCtx) error {
return nil
}
-func newRun(ctx infra.DnoteCtx) core.RunEFunc {
+func newRun(ctx context.DnoteCtx) infra.RunEFunc {
return func(cmd *cobra.Command, args []string) error {
err := Do(ctx)
if err == ErrNotLoggedIn {
diff --git a/cli/cmd/ls/ls.go b/pkg/cli/cmd/ls/ls.go
similarity index 92%
rename from cli/cmd/ls/ls.go
rename to pkg/cli/cmd/ls/ls.go
index 291d9229..8b07dd4b 100644
--- a/cli/cmd/ls/ls.go
+++ b/pkg/cli/cmd/ls/ls.go
@@ -23,9 +23,9 @@ import (
"fmt"
"strings"
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/log"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -52,7 +52,7 @@ func preRun(cmd *cobra.Command, args []string) error {
}
// NewCmd returns a new ls command
-func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
+func NewCmd(ctx context.DnoteCtx) *cobra.Command {
cmd := &cobra.Command{
Use: "ls ",
Aliases: []string{"l", "notes"},
@@ -67,7 +67,7 @@ func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
}
// NewRun returns a new run function for ls
-func NewRun(ctx infra.DnoteCtx, nameOnly bool) core.RunEFunc {
+func NewRun(ctx context.DnoteCtx, nameOnly bool) infra.RunEFunc {
return func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
if err := printBooks(ctx, nameOnly); err != nil {
@@ -133,7 +133,7 @@ func printBookLine(info bookInfo, nameOnly bool) {
}
}
-func printBooks(ctx infra.DnoteCtx, nameOnly bool) error {
+func printBooks(ctx context.DnoteCtx, nameOnly bool) error {
db := ctx.DB
rows, err := db.Query(`SELECT books.label, count(notes.uuid) note_count
@@ -165,7 +165,7 @@ func printBooks(ctx infra.DnoteCtx, nameOnly bool) error {
return nil
}
-func printNotes(ctx infra.DnoteCtx, bookName string) error {
+func printNotes(ctx context.DnoteCtx, bookName string) error {
db := ctx.DB
var bookUUID string
diff --git a/cli/cmd/remove/remove.go b/pkg/cli/cmd/remove/remove.go
similarity index 80%
rename from cli/cmd/remove/remove.go
rename to pkg/cli/cmd/remove/remove.go
index 7e6f9d0b..ef98c9dc 100644
--- a/cli/cmd/remove/remove.go
+++ b/pkg/cli/cmd/remove/remove.go
@@ -21,10 +21,13 @@ package remove
import (
"fmt"
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
- "github.com/dnote/dnote/cli/utils"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/log"
+ "github.com/dnote/dnote/pkg/cli/output"
+ "github.com/dnote/dnote/pkg/cli/ui"
+ "github.com/dnote/dnote/pkg/cli/utils"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -39,7 +42,7 @@ var example = `
dnote delete -b js`
// NewCmd returns a new remove command
-func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
+func NewCmd(ctx context.DnoteCtx) *cobra.Command {
cmd := &cobra.Command{
Use: "remove",
Short: "Remove a note or a book",
@@ -54,7 +57,7 @@ func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
return cmd
}
-func newRun(ctx infra.DnoteCtx) core.RunEFunc {
+func newRun(ctx context.DnoteCtx) infra.RunEFunc {
return func(cmd *cobra.Command, args []string) error {
if targetBookName != "" {
if err := removeBook(ctx, targetBookName); err != nil {
@@ -83,17 +86,17 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
}
}
-func removeNote(ctx infra.DnoteCtx, noteRowID string) error {
+func removeNote(ctx context.DnoteCtx, noteRowID string) error {
db := ctx.DB
- noteInfo, err := core.GetNoteInfo(ctx, noteRowID)
+ noteInfo, err := database.GetNoteInfo(db, noteRowID)
if err != nil {
return err
}
- core.PrintNoteInfo(noteInfo)
+ output.NoteInfo(noteInfo)
- ok, err := utils.AskConfirmation("remove this note?", false)
+ ok, err := ui.Confirm("remove this note?", false)
if err != nil {
return errors.Wrap(err, "getting confirmation")
}
@@ -117,15 +120,15 @@ func removeNote(ctx infra.DnoteCtx, noteRowID string) error {
return nil
}
-func removeBook(ctx infra.DnoteCtx, bookLabel string) error {
+func removeBook(ctx context.DnoteCtx, bookLabel string) error {
db := ctx.DB
- bookUUID, err := core.GetBookUUID(ctx, bookLabel)
+ bookUUID, err := database.GetBookUUID(db, bookLabel)
if err != nil {
return errors.Wrap(err, "finding book uuid")
}
- ok, err := utils.AskConfirmation(fmt.Sprintf("delete book '%s' and all its notes?", bookLabel), false)
+ ok, err := ui.Confirm(fmt.Sprintf("delete book '%s' and all its notes?", bookLabel), false)
if err != nil {
return errors.Wrap(err, "getting confirmation")
}
diff --git a/cli/cmd/root/root.go b/pkg/cli/cmd/root/root.go
similarity index 58%
rename from cli/cmd/root/root.go
rename to pkg/cli/cmd/root/root.go
index 3da8e7e0..681418d2 100644
--- a/cli/cmd/root/root.go
+++ b/pkg/cli/cmd/root/root.go
@@ -19,10 +19,11 @@
package root
import (
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/migrate"
- "github.com/pkg/errors"
+ "github.com/dnote/dnote/pkg/cli/context"
+ // "github.com/dnote/dnote/pkg/cli/core"
+ // "github.com/dnote/dnote/pkg/cli/infra"
+ // "github.com/dnote/dnote/pkg/cli/migrate"
+ // "github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -44,24 +45,24 @@ func Execute() error {
}
// Prepare initializes necessary files
-func Prepare(ctx infra.DnoteCtx) error {
- if err := core.InitFiles(ctx); err != nil {
- return errors.Wrap(err, "initializing files")
- }
-
- if err := infra.InitDB(ctx); err != nil {
- return errors.Wrap(err, "initializing database")
- }
- if err := core.InitSystem(ctx); err != nil {
- return errors.Wrap(err, "initializing system data")
- }
-
- if err := migrate.Legacy(ctx); err != nil {
- return errors.Wrap(err, "running legacy migration")
- }
- if err := migrate.Run(ctx, migrate.LocalSequence, migrate.LocalMode); err != nil {
- return errors.Wrap(err, "running migration")
- }
+func Prepare(ctx context.DnoteCtx) error {
+ // if err := core.InitFiles(ctx); err != nil {
+ // return errors.Wrap(err, "initializing files")
+ // }
+ //
+ // if err := infra.InitDB(ctx); err != nil {
+ // return errors.Wrap(err, "initializing database")
+ // }
+ // if err := core.InitSystem(ctx); err != nil {
+ // return errors.Wrap(err, "initializing system data")
+ // }
+ //
+ // if err := migrate.Legacy(ctx); err != nil {
+ // return errors.Wrap(err, "running legacy migration")
+ // }
+ // if err := migrate.Run(ctx, migrate.LocalSequence, migrate.LocalMode); err != nil {
+ // return errors.Wrap(err, "running migration")
+ // }
return nil
}
diff --git a/cli/cmd/sync/merge.go b/pkg/cli/cmd/sync/merge.go
similarity index 89%
rename from cli/cmd/sync/merge.go
rename to pkg/cli/cmd/sync/merge.go
index f558d14c..e7a6ba58 100644
--- a/cli/cmd/sync/merge.go
+++ b/pkg/cli/cmd/sync/merge.go
@@ -23,11 +23,10 @@ import (
"fmt"
"strings"
- "github.com/dnote/dnote/cli/client"
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/utils"
- "github.com/dnote/dnote/cli/utils/diff"
+ "github.com/dnote/dnote/pkg/cli/client"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/utils"
+ "github.com/dnote/dnote/pkg/cli/utils/diff"
"github.com/pkg/errors"
)
@@ -102,7 +101,7 @@ func maxInt64(a, b int64) int64 {
return b
}
-func reportBookConflict(tx *infra.DB, body, localBookUUID, serverBookUUID string) (string, error) {
+func reportBookConflict(tx *database.DB, body, localBookUUID, serverBookUUID string) (string, error) {
var builder strings.Builder
var localBookName, serverBookName string
@@ -123,14 +122,14 @@ func reportBookConflict(tx *infra.DB, body, localBookUUID, serverBookUUID string
return builder.String(), nil
}
-func getConflictsBookUUID(tx *infra.DB) (string, error) {
+func getConflictsBookUUID(tx *database.DB) (string, error) {
var ret string
err := tx.QueryRow("SELECT uuid FROM books WHERE label = ?", "conflicts").Scan(&ret)
if err == sql.ErrNoRows {
// Create a conflicts book
ret = utils.GenerateUUID()
- b := core.NewBook(ret, "conflicts", 0, false, true)
+ b := database.NewBook(ret, "conflicts", 0, false, true)
err = b.Insert(tx)
if err != nil {
tx.Rollback()
@@ -152,7 +151,7 @@ type noteMergeReport struct {
// mergeNoteFields performs a field-by-field merge between the local and the server copy. It returns a merge report
// between the local and the server copy of the note.
-func mergeNoteFields(tx *infra.DB, localNote core.Note, serverNote client.SyncFragNote) (*noteMergeReport, error) {
+func mergeNoteFields(tx *database.DB, localNote database.Note, serverNote client.SyncFragNote) (*noteMergeReport, error) {
if !localNote.Dirty {
return ¬eMergeReport{
body: serverNote.Body,
diff --git a/cli/cmd/sync/merge_test.go b/pkg/cli/cmd/sync/merge_test.go
similarity index 94%
rename from cli/cmd/sync/merge_test.go
rename to pkg/cli/cmd/sync/merge_test.go
index 499c3a90..b9a8d713 100644
--- a/cli/cmd/sync/merge_test.go
+++ b/pkg/cli/cmd/sync/merge_test.go
@@ -22,7 +22,7 @@ import (
"fmt"
"testing"
- "github.com/dnote/dnote/cli/testutils"
+ "github.com/dnote/dnote/pkg/assert"
)
func TestReportConflict(t *testing.T) {
@@ -128,7 +128,7 @@ fuuz
result := reportBodyConflict(tc.local, tc.server)
t.Run(fmt.Sprintf("test case %d", idx), func(t *testing.T) {
- testutils.AssertDeepEqual(t, result, tc.expected, "result mismatch")
+ assert.DeepEqual(t, result, tc.expected, "result mismatch")
})
}
}
diff --git a/cli/cmd/sync/sync.go b/pkg/cli/cmd/sync/sync.go
similarity index 88%
rename from cli/cmd/sync/sync.go
rename to pkg/cli/cmd/sync/sync.go
index 4eb1cb32..e7877726 100644
--- a/cli/cmd/sync/sync.go
+++ b/pkg/cli/cmd/sync/sync.go
@@ -22,12 +22,15 @@ import (
"database/sql"
"fmt"
- "github.com/dnote/dnote/cli/client"
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/crypt"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
- "github.com/dnote/dnote/cli/migrate"
+ "github.com/dnote/dnote/pkg/cli/client"
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/crypt"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/log"
+ "github.com/dnote/dnote/pkg/cli/migrate"
+ "github.com/dnote/dnote/pkg/cli/upgrade"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -43,7 +46,7 @@ var example = `
var isFullSync bool
// NewCmd returns a new sync command
-func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
+func NewCmd(ctx context.DnoteCtx) *cobra.Command {
cmd := &cobra.Command{
Use: "sync",
Aliases: []string{"s"},
@@ -58,20 +61,20 @@ func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
return cmd
}
-func getLastSyncAt(tx *infra.DB) (int, error) {
+func getLastSyncAt(tx *database.DB) (int, error) {
var ret int
- if err := core.GetSystem(tx, infra.SystemLastSyncAt, &ret); err != nil {
+ if err := database.GetSystem(tx, consts.SystemLastSyncAt, &ret); err != nil {
return ret, errors.Wrap(err, "querying last sync time")
}
return ret, nil
}
-func getLastMaxUSN(tx *infra.DB) (int, error) {
+func getLastMaxUSN(tx *database.DB) (int, error) {
var ret int
- if err := core.GetSystem(tx, infra.SystemLastMaxUSN, &ret); err != nil {
+ if err := database.GetSystem(tx, consts.SystemLastMaxUSN, &ret); err != nil {
return ret, errors.Wrap(err, "querying last user max_usn")
}
@@ -152,7 +155,7 @@ func processFragments(fragments []client.SyncFragment, cipherKey []byte) (syncLi
// getSyncList gets a list of all sync fragments after the specified usn
// and aggregates them into a syncList data structure
-func getSyncList(ctx infra.DnoteCtx, afterUSN int) (syncList, error) {
+func getSyncList(ctx context.DnoteCtx, afterUSN int) (syncList, error) {
fragments, err := getSyncFragments(ctx, afterUSN)
if err != nil {
return syncList{}, errors.Wrap(err, "getting sync fragments")
@@ -168,7 +171,7 @@ func getSyncList(ctx infra.DnoteCtx, afterUSN int) (syncList, error) {
// getSyncFragments repeatedly gets all sync fragments after the specified usn until there is no more new data
// remaining and returns the buffered list
-func getSyncFragments(ctx infra.DnoteCtx, afterUSN int) ([]client.SyncFragment, error) {
+func getSyncFragments(ctx context.DnoteCtx, afterUSN int) ([]client.SyncFragment, error) {
var buf []client.SyncFragment
nextAfterUSN := afterUSN
@@ -197,7 +200,7 @@ func getSyncFragments(ctx infra.DnoteCtx, afterUSN int) ([]client.SyncFragment,
// resolveLabel resolves a book label conflict by repeatedly appending an increasing integer
// to the label until it finds a unique label. It returns the first non-conflicting label.
-func resolveLabel(tx *infra.DB, label string) (string, error) {
+func resolveLabel(tx *database.DB, label string) (string, error) {
var ret string
for i := 2; ; i++ {
@@ -218,7 +221,7 @@ func resolveLabel(tx *infra.DB, label string) (string, error) {
// mergeBook inserts or updates the given book in the local database.
// If a book with a duplicate label exists locally, it renames the duplicate by appending a number.
-func mergeBook(tx *infra.DB, b client.SyncFragBook, mode int) error {
+func mergeBook(tx *database.DB, b client.SyncFragBook, mode int) error {
var count int
if err := tx.QueryRow("SELECT count(*) FROM books WHERE label = ?", b.Label).Scan(&count); err != nil {
return errors.Wrapf(err, "checking for books with a duplicate label %s", b.Label)
@@ -237,7 +240,7 @@ func mergeBook(tx *infra.DB, b client.SyncFragBook, mode int) error {
}
if mode == modeInsert {
- book := core.NewBook(b.UUID, b.Label, b.USN, false, false)
+ book := database.NewBook(b.UUID, b.Label, b.USN, false, false)
if err := book.Insert(tx); err != nil {
return errors.Wrapf(err, "inserting note with uuid %s", b.UUID)
}
@@ -252,7 +255,7 @@ func mergeBook(tx *infra.DB, b client.SyncFragBook, mode int) error {
return nil
}
-func stepSyncBook(tx *infra.DB, b client.SyncFragBook) error {
+func stepSyncBook(tx *database.DB, b client.SyncFragBook) error {
var localUSN int
var dirty bool
err := tx.QueryRow("SELECT usn, dirty FROM books WHERE uuid = ?", b.UUID).Scan(&localUSN, &dirty)
@@ -276,7 +279,7 @@ func stepSyncBook(tx *infra.DB, b client.SyncFragBook) error {
return nil
}
-func mergeNote(tx *infra.DB, serverNote client.SyncFragNote, localNote core.Note) error {
+func mergeNote(tx *database.DB, serverNote client.SyncFragNote, localNote database.Note) error {
var bookDeleted bool
err := tx.QueryRow("SELECT deleted FROM books WHERE uuid = ?", localNote.BookUUID).Scan(&bookDeleted)
if err != nil {
@@ -311,8 +314,8 @@ func mergeNote(tx *infra.DB, serverNote client.SyncFragNote, localNote core.Note
return nil
}
-func stepSyncNote(tx *infra.DB, n client.SyncFragNote) error {
- var localNote core.Note
+func stepSyncNote(tx *database.DB, n client.SyncFragNote) error {
+ var localNote database.Note
err := tx.QueryRow("SELECT body, usn, book_uuid, dirty, deleted FROM notes WHERE uuid = ?", n.UUID).
Scan(&localNote.Body, &localNote.USN, &localNote.BookUUID, &localNote.Dirty, &localNote.Deleted)
if err != nil && err != sql.ErrNoRows {
@@ -321,7 +324,7 @@ func stepSyncNote(tx *infra.DB, n client.SyncFragNote) error {
// if note exists in the server and does not exist in the client, insert the note.
if err == sql.ErrNoRows {
- note := core.NewNote(n.UUID, n.BookUUID, n.Body, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, false)
+ note := database.NewNote(n.UUID, n.BookUUID, n.Body, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, false)
if err := note.Insert(tx); err != nil {
return errors.Wrapf(err, "inserting note with uuid %s", n.UUID)
@@ -335,8 +338,8 @@ func stepSyncNote(tx *infra.DB, n client.SyncFragNote) error {
return nil
}
-func fullSyncNote(tx *infra.DB, n client.SyncFragNote) error {
- var localNote core.Note
+func fullSyncNote(tx *database.DB, n client.SyncFragNote) error {
+ var localNote database.Note
err := tx.QueryRow("SELECT body, usn, book_uuid, dirty, deleted FROM notes WHERE uuid = ?", n.UUID).
Scan(&localNote.Body, &localNote.USN, &localNote.BookUUID, &localNote.Dirty, &localNote.Deleted)
if err != nil && err != sql.ErrNoRows {
@@ -345,7 +348,7 @@ func fullSyncNote(tx *infra.DB, n client.SyncFragNote) error {
// if note exists in the server and does not exist in the client, insert the note.
if err == sql.ErrNoRows {
- note := core.NewNote(n.UUID, n.BookUUID, n.Body, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, false)
+ note := database.NewNote(n.UUID, n.BookUUID, n.Body, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, false)
if err := note.Insert(tx); err != nil {
return errors.Wrapf(err, "inserting note with uuid %s", n.UUID)
@@ -359,7 +362,7 @@ func fullSyncNote(tx *infra.DB, n client.SyncFragNote) error {
return nil
}
-func syncDeleteNote(tx *infra.DB, noteUUID string) error {
+func syncDeleteNote(tx *database.DB, noteUUID string) error {
var localUSN int
var dirty bool
err := tx.QueryRow("SELECT usn, dirty FROM notes WHERE uuid = ?", noteUUID).Scan(&localUSN, &dirty)
@@ -384,7 +387,7 @@ func syncDeleteNote(tx *infra.DB, noteUUID string) error {
}
// checkNotesPristine checks that none of the notes in the given book are dirty
-func checkNotesPristine(tx *infra.DB, bookUUID string) (bool, error) {
+func checkNotesPristine(tx *database.DB, bookUUID string) (bool, error) {
var count int
if err := tx.QueryRow("SELECT count(*) FROM notes WHERE book_uuid = ? AND dirty = ?", bookUUID, true).Scan(&count); err != nil {
return false, errors.Wrapf(err, "counting notes that are dirty in book %s", bookUUID)
@@ -397,7 +400,7 @@ func checkNotesPristine(tx *infra.DB, bookUUID string) (bool, error) {
return true, nil
}
-func syncDeleteBook(tx *infra.DB, bookUUID string) error {
+func syncDeleteBook(tx *database.DB, bookUUID string) error {
var localUSN int
var dirty bool
err := tx.QueryRow("SELECT usn, dirty FROM books WHERE uuid = ?", bookUUID).Scan(&localUSN, &dirty)
@@ -443,7 +446,7 @@ func syncDeleteBook(tx *infra.DB, bookUUID string) error {
return nil
}
-func fullSyncBook(tx *infra.DB, b client.SyncFragBook) error {
+func fullSyncBook(tx *database.DB, b client.SyncFragBook) error {
var localUSN int
var dirty bool
err := tx.QueryRow("SELECT usn, dirty FROM books WHERE uuid = ?", b.UUID).Scan(&localUSN, &dirty)
@@ -495,7 +498,7 @@ func checkBookInList(uuid string, list *syncList) bool {
// judging by the full list of resources in the server. Concretely, the only acceptable
// situation in which a local note is not present in the server is if it is new and has not been
// uploaded (i.e. dirty and usn is 0). Otherwise, it is a result of some kind of error and should be cleaned.
-func cleanLocalNotes(tx *infra.DB, fullList *syncList) error {
+func cleanLocalNotes(tx *database.DB, fullList *syncList) error {
rows, err := tx.Query("SELECT uuid, usn, dirty FROM notes")
if err != nil {
return errors.Wrap(err, "getting local notes")
@@ -503,7 +506,7 @@ func cleanLocalNotes(tx *infra.DB, fullList *syncList) error {
defer rows.Close()
for rows.Next() {
- var note core.Note
+ var note database.Note
if err := rows.Scan(¬e.UUID, ¬e.USN, ¬e.Dirty); err != nil {
return errors.Wrap(err, "scanning a row for local note")
}
@@ -521,7 +524,7 @@ func cleanLocalNotes(tx *infra.DB, fullList *syncList) error {
}
// cleanLocalBooks deletes from the local database any books that are in invalid state
-func cleanLocalBooks(tx *infra.DB, fullList *syncList) error {
+func cleanLocalBooks(tx *database.DB, fullList *syncList) error {
rows, err := tx.Query("SELECT uuid, usn, dirty FROM books")
if err != nil {
return errors.Wrap(err, "getting local books")
@@ -529,7 +532,7 @@ func cleanLocalBooks(tx *infra.DB, fullList *syncList) error {
defer rows.Close()
for rows.Next() {
- var book core.Book
+ var book database.Book
if err := rows.Scan(&book.UUID, &book.USN, &book.Dirty); err != nil {
return errors.Wrap(err, "scanning a row for local book")
}
@@ -546,7 +549,7 @@ func cleanLocalBooks(tx *infra.DB, fullList *syncList) error {
return nil
}
-func fullSync(ctx infra.DnoteCtx, tx *infra.DB) error {
+func fullSync(ctx context.DnoteCtx, tx *database.DB) error {
log.Debug("performing a full sync\n")
log.Info("resolving delta.")
@@ -597,7 +600,7 @@ func fullSync(ctx infra.DnoteCtx, tx *infra.DB) error {
return nil
}
-func stepSync(ctx infra.DnoteCtx, tx *infra.DB, afterUSN int) error {
+func stepSync(ctx context.DnoteCtx, tx *database.DB, afterUSN int) error {
log.Debug("performing a step sync\n")
log.Info("resolving delta.")
@@ -641,7 +644,7 @@ func stepSync(ctx infra.DnoteCtx, tx *infra.DB, afterUSN int) error {
return nil
}
-func sendBooks(ctx infra.DnoteCtx, tx *infra.DB) (bool, error) {
+func sendBooks(ctx context.DnoteCtx, tx *database.DB) (bool, error) {
isBehind := false
rows, err := tx.Query("SELECT uuid, label, usn, deleted FROM books WHERE dirty")
@@ -651,7 +654,7 @@ func sendBooks(ctx infra.DnoteCtx, tx *infra.DB) (bool, error) {
defer rows.Close()
for rows.Next() {
- var book core.Book
+ var book database.Book
if err = rows.Scan(&book.UUID, &book.Label, &book.USN, &book.Deleted); err != nil {
return isBehind, errors.Wrap(err, "scanning a syncable book")
@@ -745,7 +748,7 @@ func sendBooks(ctx infra.DnoteCtx, tx *infra.DB) (bool, error) {
return isBehind, nil
}
-func sendNotes(ctx infra.DnoteCtx, tx *infra.DB) (bool, error) {
+func sendNotes(ctx context.DnoteCtx, tx *database.DB) (bool, error) {
isBehind := false
rows, err := tx.Query("SELECT uuid, book_uuid, body, public, deleted, usn, added_on FROM notes WHERE dirty")
@@ -755,7 +758,7 @@ func sendNotes(ctx infra.DnoteCtx, tx *infra.DB) (bool, error) {
defer rows.Close()
for rows.Next() {
- var note core.Note
+ var note database.Note
if err = rows.Scan(¬e.UUID, ¬e.BookUUID, ¬e.Body, ¬e.Public, ¬e.Deleted, ¬e.USN, ¬e.AddedOn); err != nil {
return isBehind, errors.Wrap(err, "scanning a syncable note")
@@ -845,7 +848,7 @@ func sendNotes(ctx infra.DnoteCtx, tx *infra.DB) (bool, error) {
return isBehind, nil
}
-func sendChanges(ctx infra.DnoteCtx, tx *infra.DB) (bool, error) {
+func sendChanges(ctx context.DnoteCtx, tx *database.DB) (bool, error) {
log.Info("sending changes.")
var delta int
@@ -870,23 +873,23 @@ func sendChanges(ctx infra.DnoteCtx, tx *infra.DB) (bool, error) {
return isBehind, nil
}
-func updateLastMaxUSN(tx *infra.DB, val int) error {
- if err := core.UpdateSystem(tx, infra.SystemLastMaxUSN, val); err != nil {
- return errors.Wrapf(err, "updating %s", infra.SystemLastMaxUSN)
+func updateLastMaxUSN(tx *database.DB, val int) error {
+ if err := database.UpdateSystem(tx, consts.SystemLastMaxUSN, val); err != nil {
+ return errors.Wrapf(err, "updating %s", consts.SystemLastMaxUSN)
}
return nil
}
-func updateLastSyncAt(tx *infra.DB, val int64) error {
- if err := core.UpdateSystem(tx, infra.SystemLastSyncAt, val); err != nil {
- return errors.Wrapf(err, "updating %s", infra.SystemLastSyncAt)
+func updateLastSyncAt(tx *database.DB, val int64) error {
+ if err := database.UpdateSystem(tx, consts.SystemLastSyncAt, val); err != nil {
+ return errors.Wrapf(err, "updating %s", consts.SystemLastSyncAt)
}
return nil
}
-func saveSyncState(tx *infra.DB, serverTime int64, serverMaxUSN int) error {
+func saveSyncState(tx *database.DB, serverTime int64, serverMaxUSN int) error {
if err := updateLastMaxUSN(tx, serverMaxUSN); err != nil {
return errors.Wrap(err, "updating last max usn")
}
@@ -897,7 +900,7 @@ func saveSyncState(tx *infra.DB, serverTime int64, serverMaxUSN int) error {
return nil
}
-func newRun(ctx infra.DnoteCtx) core.RunEFunc {
+func newRun(ctx context.DnoteCtx) infra.RunEFunc {
return func(cmd *cobra.Command, args []string) error {
if ctx.SessionKey == "" || ctx.CipherKey == nil {
return errors.New("not logged in")
@@ -971,7 +974,7 @@ func newRun(ctx infra.DnoteCtx) core.RunEFunc {
log.Success("success\n")
- if err := core.CheckUpdate(ctx); err != nil {
+ if err := upgrade.Check(ctx); err != nil {
log.Error(errors.Wrap(err, "automatically checking updates").Error())
}
diff --git a/cli/cmd/sync/sync_test.go b/pkg/cli/cmd/sync/sync_test.go
similarity index 50%
rename from cli/cmd/sync/sync_test.go
rename to pkg/cli/cmd/sync/sync_test.go
index 00ee936c..8959c30a 100644
--- a/cli/cmd/sync/sync_test.go
+++ b/pkg/cli/cmd/sync/sync_test.go
@@ -27,22 +27,21 @@ import (
"strings"
"testing"
- "github.com/dnote/dnote/cli/client"
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/crypt"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/testutils"
- "github.com/dnote/dnote/cli/utils"
+ "github.com/dnote/dnote/pkg/assert"
+ "github.com/dnote/dnote/pkg/cli/client"
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/crypt"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/testutils"
+ "github.com/dnote/dnote/pkg/cli/utils"
"github.com/pkg/errors"
)
var cipherKey = []byte("AES256Key-32Characters1234567890")
+var dbPath = "../../tmp/.dnote.db"
func TestProcessFragments(t *testing.T) {
- // set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
fragments := []client.SyncFragment{
client.SyncFragment{
FragMaxUSN: 10,
@@ -107,16 +106,14 @@ func TestProcessFragments(t *testing.T) {
}
// test
- testutils.AssertDeepEqual(t, sl, expected, "syncList mismatch")
+ assert.DeepEqual(t, sl, expected, "syncList mismatch")
}
func TestGetLastSyncAt(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
- testutils.MustExec(t, "setting up last_sync_at", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastSyncAt, 1541108743)
+ db := database.InitTestDB(t, "../../tmp/.dnote", nil)
+ defer database.CloseTestDB(t, db)
+ database.MustExec(t, "setting up last_sync_at", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastSyncAt, 1541108743)
// exec
tx, err := db.Begin()
@@ -132,16 +129,14 @@ func TestGetLastSyncAt(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, got, 1541108743, "last_sync_at mismatch")
+ assert.Equal(t, got, 1541108743, "last_sync_at mismatch")
}
func TestGetLastMaxUSN(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
- testutils.MustExec(t, "setting up last_max_usn", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, 20001)
+ db := database.InitTestDB(t, "../../tmp/.dnote", nil)
+ defer database.CloseTestDB(t, db)
+ database.MustExec(t, "setting up last_max_usn", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastMaxUSN, 20001)
// exec
tx, err := db.Begin()
@@ -157,7 +152,7 @@ func TestGetLastMaxUSN(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, got, 20001, "last_max_usn mismatch")
+ assert.Equal(t, got, 20001, "last_max_usn mismatch")
}
func TestResolveLabel(t *testing.T) {
@@ -186,17 +181,15 @@ func TestResolveLabel(t *testing.T) {
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, "../../tmp/.dnote", nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
-
- testutils.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b1-uuid", "js")
- testutils.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b2-uuid", "css_2")
- testutils.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b3-uuid", "linux_(1)")
- testutils.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b4-uuid", "linux_2")
- testutils.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b5-uuid", "linux_3")
- testutils.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b6-uuid", "cool_ideas")
+ database.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b1-uuid", "js")
+ database.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b2-uuid", "css_2")
+ database.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b3-uuid", "linux_(1)")
+ database.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b4-uuid", "linux_2")
+ database.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b5-uuid", "linux_3")
+ database.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b6-uuid", "cool_ideas")
// execute
tx, err := db.Begin()
@@ -210,7 +203,7 @@ func TestResolveLabel(t *testing.T) {
}
tx.Rollback()
- testutils.AssertEqual(t, got, tc.expected, fmt.Sprintf("output mismatch for test case %d", idx))
+ assert.Equal(t, got, tc.expected, fmt.Sprintf("output mismatch for test case %d", idx))
}()
}
}
@@ -218,10 +211,8 @@ func TestResolveLabel(t *testing.T) {
func TestSyncDeleteNote(t *testing.T) {
t.Run("exists on server only", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
// execute
tx, err := db.Begin()
@@ -238,32 +229,30 @@ func TestSyncDeleteNote(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 0, "book count mismatch")
+ assert.Equalf(t, noteCount, 0, "note count mismatch")
+ assert.Equalf(t, bookCount, 0, "book count mismatch")
})
t.Run("local copy is dirty", func(t *testing.T) {
b1UUID := utils.GenerateUUID()
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
+ database.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
+ database.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, true)
+ database.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 11, "n2 body", 1541108743, false, true)
- testutils.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
- testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, true)
- testutils.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 11, "n2 body", 1541108743, false, true)
-
- var n1 core.Note
- testutils.MustScan(t, "getting n1 for test case",
+ var n1 database.Note
+ database.MustScan(t, "getting n1 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Deleted, &n1.Dirty)
- var n2 core.Note
- testutils.MustScan(t, "getting n2 for test case",
+ var n2 database.Note
+ database.MustScan(t, "getting n2 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", "n2-uuid"),
&n2.UUID, &n2.BookUUID, &n2.USN, &n2.AddedOn, &n2.EditedOn, &n2.Body, &n2.Deleted, &n2.Dirty)
@@ -282,60 +271,58 @@ func TestSyncDeleteNote(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes for test case", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books for test case", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes for test case", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books for test case", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
// do not delete note if local copy is dirty
- testutils.AssertEqualf(t, noteCount, 2, "note count mismatch for test case")
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch for test case")
+ assert.Equalf(t, noteCount, 2, "note count mismatch for test case")
+ assert.Equalf(t, bookCount, 1, "book count mismatch for test case")
- var n1Record core.Note
- testutils.MustScan(t, "getting n1 for test case",
+ var n1Record database.Note
+ database.MustScan(t, "getting n1 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", n1.UUID),
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.Body, &n1Record.Deleted, &n1Record.Dirty)
- var n2Record core.Note
- testutils.MustScan(t, "getting n2 for test case",
+ var n2Record database.Note
+ database.MustScan(t, "getting n2 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
&n2Record.UUID, &n2Record.BookUUID, &n2Record.USN, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.Body, &n2Record.Deleted, &n2Record.Dirty)
- testutils.AssertEqual(t, n1Record.UUID, n1.UUID, "n1 UUID mismatch for test case")
- testutils.AssertEqual(t, n1Record.BookUUID, n1.BookUUID, "n1 BookUUID mismatch for test case")
- testutils.AssertEqual(t, n1Record.USN, n1.USN, "n1 USN mismatch for test case")
- testutils.AssertEqual(t, n1Record.AddedOn, n1.AddedOn, "n1 AddedOn mismatch for test case")
- testutils.AssertEqual(t, n1Record.EditedOn, n1.EditedOn, "n1 EditedOn mismatch for test case")
- testutils.AssertEqual(t, n1Record.Body, n1.Body, "n1 Body mismatch for test case")
- testutils.AssertEqual(t, n1Record.Deleted, n1.Deleted, "n1 Deleted mismatch for test case")
- testutils.AssertEqual(t, n1Record.Dirty, n1.Dirty, "n1 Dirty mismatch for test case")
+ assert.Equal(t, n1Record.UUID, n1.UUID, "n1 UUID mismatch for test case")
+ assert.Equal(t, n1Record.BookUUID, n1.BookUUID, "n1 BookUUID mismatch for test case")
+ assert.Equal(t, n1Record.USN, n1.USN, "n1 USN mismatch for test case")
+ assert.Equal(t, n1Record.AddedOn, n1.AddedOn, "n1 AddedOn mismatch for test case")
+ assert.Equal(t, n1Record.EditedOn, n1.EditedOn, "n1 EditedOn mismatch for test case")
+ assert.Equal(t, n1Record.Body, n1.Body, "n1 Body mismatch for test case")
+ assert.Equal(t, n1Record.Deleted, n1.Deleted, "n1 Deleted mismatch for test case")
+ assert.Equal(t, n1Record.Dirty, n1.Dirty, "n1 Dirty mismatch for test case")
- testutils.AssertEqual(t, n2Record.UUID, n2.UUID, "n2 UUID mismatch for test case")
- testutils.AssertEqual(t, n2Record.BookUUID, n2.BookUUID, "n2 BookUUID mismatch for test case")
- testutils.AssertEqual(t, n2Record.USN, n2.USN, "n2 USN mismatch for test case")
- testutils.AssertEqual(t, n2Record.AddedOn, n2.AddedOn, "n2 AddedOn mismatch for test case")
- testutils.AssertEqual(t, n2Record.EditedOn, n2.EditedOn, "n2 EditedOn mismatch for test case")
- testutils.AssertEqual(t, n2Record.Body, n2.Body, "n2 Body mismatch for test case")
- testutils.AssertEqual(t, n2Record.Deleted, n2.Deleted, "n2 Deleted mismatch for test case")
- testutils.AssertEqual(t, n2Record.Dirty, n2.Dirty, "n2 Dirty mismatch for test case")
+ assert.Equal(t, n2Record.UUID, n2.UUID, "n2 UUID mismatch for test case")
+ assert.Equal(t, n2Record.BookUUID, n2.BookUUID, "n2 BookUUID mismatch for test case")
+ assert.Equal(t, n2Record.USN, n2.USN, "n2 USN mismatch for test case")
+ assert.Equal(t, n2Record.AddedOn, n2.AddedOn, "n2 AddedOn mismatch for test case")
+ assert.Equal(t, n2Record.EditedOn, n2.EditedOn, "n2 EditedOn mismatch for test case")
+ assert.Equal(t, n2Record.Body, n2.Body, "n2 Body mismatch for test case")
+ assert.Equal(t, n2Record.Deleted, n2.Deleted, "n2 Deleted mismatch for test case")
+ assert.Equal(t, n2Record.Dirty, n2.Dirty, "n2 Dirty mismatch for test case")
})
t.Run("local copy is not dirty", func(t *testing.T) {
b1UUID := utils.GenerateUUID()
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
+ database.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
+ database.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, false)
+ database.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 11, "n2 body", 1541108743, false, false)
- testutils.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
- testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, false)
- testutils.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 11, "n2 body", 1541108743, false, false)
-
- var n1 core.Note
- testutils.MustScan(t, "getting n1 for test case",
+ var n1 database.Note
+ database.MustScan(t, "getting n1 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Deleted, &n1.Dirty)
- var n2 core.Note
- testutils.MustScan(t, "getting n2 for test case",
+ var n2 database.Note
+ database.MustScan(t, "getting n2 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", "n2-uuid"),
&n2.UUID, &n2.BookUUID, &n2.USN, &n2.AddedOn, &n2.EditedOn, &n2.Body, &n2.Deleted, &n2.Dirty)
@@ -354,39 +341,37 @@ func TestSyncDeleteNote(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes for test case", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books for test case", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes for test case", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books for test case", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 1, "note count mismatch for test case")
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch for test case")
+ assert.Equalf(t, noteCount, 1, "note count mismatch for test case")
+ assert.Equalf(t, bookCount, 1, "book count mismatch for test case")
- var n2Record core.Note
- testutils.MustScan(t, "getting n2 for test case",
+ var n2Record database.Note
+ database.MustScan(t, "getting n2 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
&n2Record.UUID, &n2Record.BookUUID, &n2Record.USN, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.Body, &n2Record.Deleted, &n2Record.Dirty)
- testutils.AssertEqual(t, n2Record.UUID, n2.UUID, "n2 UUID mismatch for test case")
- testutils.AssertEqual(t, n2Record.BookUUID, n2.BookUUID, "n2 BookUUID mismatch for test case")
- testutils.AssertEqual(t, n2Record.USN, n2.USN, "n2 USN mismatch for test case")
- testutils.AssertEqual(t, n2Record.AddedOn, n2.AddedOn, "n2 AddedOn mismatch for test case")
- testutils.AssertEqual(t, n2Record.EditedOn, n2.EditedOn, "n2 EditedOn mismatch for test case")
- testutils.AssertEqual(t, n2Record.Body, n2.Body, "n2 Body mismatch for test case")
- testutils.AssertEqual(t, n2Record.Deleted, n2.Deleted, "n2 Deleted mismatch for test case")
- testutils.AssertEqual(t, n2Record.Dirty, n2.Dirty, "n2 Dirty mismatch for test case")
+ assert.Equal(t, n2Record.UUID, n2.UUID, "n2 UUID mismatch for test case")
+ assert.Equal(t, n2Record.BookUUID, n2.BookUUID, "n2 BookUUID mismatch for test case")
+ assert.Equal(t, n2Record.USN, n2.USN, "n2 USN mismatch for test case")
+ assert.Equal(t, n2Record.AddedOn, n2.AddedOn, "n2 AddedOn mismatch for test case")
+ assert.Equal(t, n2Record.EditedOn, n2.EditedOn, "n2 EditedOn mismatch for test case")
+ assert.Equal(t, n2Record.Body, n2.Body, "n2 Body mismatch for test case")
+ assert.Equal(t, n2Record.Deleted, n2.Deleted, "n2 Deleted mismatch for test case")
+ assert.Equal(t, n2Record.Dirty, n2.Dirty, "n2 Dirty mismatch for test case")
})
}
func TestSyncDeleteBook(t *testing.T) {
t.Run("exists on server only", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
+ database.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b1-uuid", "b1-label")
- db := ctx.DB
- testutils.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", "b1-uuid", "b1-label")
-
- var b1 core.Book
- testutils.MustScan(t, "getting b1 for test case",
+ var b1 database.Book
+ database.MustScan(t, "getting b1 for test case",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b1-uuid"),
&b1.UUID, &b1.Label, &b1.USN, &b1.Dirty)
@@ -405,41 +390,39 @@ func TestSyncDeleteBook(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch")
+ assert.Equalf(t, noteCount, 0, "note count mismatch")
+ assert.Equalf(t, bookCount, 1, "book count mismatch")
- var b1Record core.Book
- testutils.MustScan(t, "getting b1 for test case",
+ var b1Record database.Book
+ database.MustScan(t, "getting b1 for test case",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b1-uuid"),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
- testutils.AssertEqual(t, b1Record.UUID, b1.UUID, "b1 UUID mismatch for test case")
- testutils.AssertEqual(t, b1Record.Label, b1.Label, "b1 Label mismatch for test case")
- testutils.AssertEqual(t, b1Record.USN, b1.USN, "b1 USN mismatch for test case")
- testutils.AssertEqual(t, b1Record.Dirty, b1.Dirty, "b1 Dirty mismatch for test case")
+ assert.Equal(t, b1Record.UUID, b1.UUID, "b1 UUID mismatch for test case")
+ assert.Equal(t, b1Record.Label, b1.Label, "b1 Label mismatch for test case")
+ assert.Equal(t, b1Record.USN, b1.USN, "b1 USN mismatch for test case")
+ assert.Equal(t, b1Record.Dirty, b1.Dirty, "b1 Dirty mismatch for test case")
})
t.Run("local copy is dirty", func(t *testing.T) {
b1UUID := utils.GenerateUUID()
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
+ database.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", b1UUID, "b1-label", 12, true)
+ database.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, true)
- testutils.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", b1UUID, "b1-label", 12, true)
- testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, true)
-
- var b1 core.Book
- testutils.MustScan(t, "getting b1 for test case",
+ var b1 database.Book
+ database.MustScan(t, "getting b1 for test case",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", b1UUID),
&b1.UUID, &b1.Label, &b1.USN, &b1.Dirty)
- var n1 core.Note
- testutils.MustScan(t, "getting n1 for test case",
+ var n1 database.Note
+ database.MustScan(t, "getting n1 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Deleted, &n1.Dirty)
@@ -458,35 +441,35 @@ func TestSyncDeleteBook(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes for test case", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books for test case", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes for test case", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books for test case", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
// do not delete note if local copy is dirty
- testutils.AssertEqualf(t, noteCount, 1, "note count mismatch for test case")
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch for test case")
+ assert.Equalf(t, noteCount, 1, "note count mismatch for test case")
+ assert.Equalf(t, bookCount, 1, "book count mismatch for test case")
- var b1Record core.Book
- testutils.MustScan(t, "getting b1Record for test case",
+ var b1Record database.Book
+ database.MustScan(t, "getting b1Record for test case",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", b1UUID),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
- var n1Record core.Note
- testutils.MustScan(t, "getting n1 for test case",
+ var n1Record database.Note
+ database.MustScan(t, "getting n1 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", n1.UUID),
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.Body, &n1Record.Deleted, &n1Record.Dirty)
- testutils.AssertEqual(t, b1Record.UUID, b1.UUID, "b1 UUID mismatch for test case")
- testutils.AssertEqual(t, b1Record.Label, b1.Label, "b1 Label mismatch for test case")
- testutils.AssertEqual(t, b1Record.USN, b1.USN, "b1 USN mismatch for test case")
- testutils.AssertEqual(t, b1Record.Dirty, b1.Dirty, "b1 Dirty mismatch for test case")
+ assert.Equal(t, b1Record.UUID, b1.UUID, "b1 UUID mismatch for test case")
+ assert.Equal(t, b1Record.Label, b1.Label, "b1 Label mismatch for test case")
+ assert.Equal(t, b1Record.USN, b1.USN, "b1 USN mismatch for test case")
+ assert.Equal(t, b1Record.Dirty, b1.Dirty, "b1 Dirty mismatch for test case")
- testutils.AssertEqual(t, n1Record.UUID, n1.UUID, "n1 UUID mismatch for test case")
- testutils.AssertEqual(t, n1Record.BookUUID, n1.BookUUID, "n1 BookUUID mismatch for test case")
- testutils.AssertEqual(t, n1Record.USN, n1.USN, "n1 USN mismatch for test case")
- testutils.AssertEqual(t, n1Record.AddedOn, n1.AddedOn, "n1 AddedOn mismatch for test case")
- testutils.AssertEqual(t, n1Record.EditedOn, n1.EditedOn, "n1 EditedOn mismatch for test case")
- testutils.AssertEqual(t, n1Record.Body, n1.Body, "n1 Body mismatch for test case")
- testutils.AssertEqual(t, n1Record.Deleted, n1.Deleted, "n1 Deleted mismatch for test case")
- testutils.AssertEqual(t, n1Record.Dirty, n1.Dirty, "n1 Dirty mismatch for test case")
+ assert.Equal(t, n1Record.UUID, n1.UUID, "n1 UUID mismatch for test case")
+ assert.Equal(t, n1Record.BookUUID, n1.BookUUID, "n1 BookUUID mismatch for test case")
+ assert.Equal(t, n1Record.USN, n1.USN, "n1 USN mismatch for test case")
+ assert.Equal(t, n1Record.AddedOn, n1.AddedOn, "n1 AddedOn mismatch for test case")
+ assert.Equal(t, n1Record.EditedOn, n1.EditedOn, "n1 EditedOn mismatch for test case")
+ assert.Equal(t, n1Record.Body, n1.Body, "n1 Body mismatch for test case")
+ assert.Equal(t, n1Record.Deleted, n1.Deleted, "n1 Deleted mismatch for test case")
+ assert.Equal(t, n1Record.Dirty, n1.Dirty, "n1 Dirty mismatch for test case")
})
t.Run("local copy is not dirty", func(t *testing.T) {
@@ -494,22 +477,20 @@ func TestSyncDeleteBook(t *testing.T) {
b2UUID := utils.GenerateUUID()
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
+ database.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
+ database.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, false)
+ database.MustExec(t, "inserting b2 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "b2-label")
+ database.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b2UUID, 11, "n2 body", 1541108743, false, false)
- testutils.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
- testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, false)
- testutils.MustExec(t, "inserting b2 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "b2-label")
- testutils.MustExec(t, "inserting n2 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b2UUID, 11, "n2 body", 1541108743, false, false)
-
- var b2 core.Book
- testutils.MustScan(t, "getting b2 for test case",
+ var b2 database.Book
+ database.MustScan(t, "getting b2 for test case",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", b2UUID),
&b2.UUID, &b2.Label, &b2.USN, &b2.Dirty)
- var n2 core.Note
- testutils.MustScan(t, "getting n2 for test case",
+ var n2 database.Note
+ database.MustScan(t, "getting n2 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", "n2-uuid"),
&n2.UUID, &n2.BookUUID, &n2.USN, &n2.AddedOn, &n2.EditedOn, &n2.Body, &n2.Deleted, &n2.Dirty)
@@ -528,47 +509,45 @@ func TestSyncDeleteBook(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes for test case", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books for test case", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes for test case", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books for test case", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 1, "note count mismatch for test case")
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch for test case")
+ assert.Equalf(t, noteCount, 1, "note count mismatch for test case")
+ assert.Equalf(t, bookCount, 1, "book count mismatch for test case")
- var b2Record core.Book
- testutils.MustScan(t, "getting b2 for test case",
+ var b2Record database.Book
+ database.MustScan(t, "getting b2 for test case",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", b2UUID),
&b2Record.UUID, &b2Record.Label, &b2Record.USN, &b2Record.Dirty)
- var n2Record core.Note
- testutils.MustScan(t, "getting n2 for test case",
+ var n2Record database.Note
+ database.MustScan(t, "getting n2 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
&n2Record.UUID, &n2Record.BookUUID, &n2Record.USN, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.Body, &n2Record.Deleted, &n2Record.Dirty)
- testutils.AssertEqual(t, b2Record.UUID, b2.UUID, "b2 UUID mismatch for test case")
- testutils.AssertEqual(t, b2Record.Label, b2.Label, "b2 Label mismatch for test case")
- testutils.AssertEqual(t, b2Record.USN, b2.USN, "b2 USN mismatch for test case")
- testutils.AssertEqual(t, b2Record.Dirty, b2.Dirty, "b2 Dirty mismatch for test case")
+ assert.Equal(t, b2Record.UUID, b2.UUID, "b2 UUID mismatch for test case")
+ assert.Equal(t, b2Record.Label, b2.Label, "b2 Label mismatch for test case")
+ assert.Equal(t, b2Record.USN, b2.USN, "b2 USN mismatch for test case")
+ assert.Equal(t, b2Record.Dirty, b2.Dirty, "b2 Dirty mismatch for test case")
- testutils.AssertEqual(t, n2Record.UUID, n2.UUID, "n2 UUID mismatch for test case")
- testutils.AssertEqual(t, n2Record.BookUUID, n2.BookUUID, "n2 BookUUID mismatch for test case")
- testutils.AssertEqual(t, n2Record.USN, n2.USN, "n2 USN mismatch for test case")
- testutils.AssertEqual(t, n2Record.AddedOn, n2.AddedOn, "n2 AddedOn mismatch for test case")
- testutils.AssertEqual(t, n2Record.EditedOn, n2.EditedOn, "n2 EditedOn mismatch for test case")
- testutils.AssertEqual(t, n2Record.Body, n2.Body, "n2 Body mismatch for test case")
- testutils.AssertEqual(t, n2Record.Deleted, n2.Deleted, "n2 Deleted mismatch for test case")
- testutils.AssertEqual(t, n2Record.Dirty, n2.Dirty, "n2 Dirty mismatch for test case")
+ assert.Equal(t, n2Record.UUID, n2.UUID, "n2 UUID mismatch for test case")
+ assert.Equal(t, n2Record.BookUUID, n2.BookUUID, "n2 BookUUID mismatch for test case")
+ assert.Equal(t, n2Record.USN, n2.USN, "n2 USN mismatch for test case")
+ assert.Equal(t, n2Record.AddedOn, n2.AddedOn, "n2 AddedOn mismatch for test case")
+ assert.Equal(t, n2Record.EditedOn, n2.EditedOn, "n2 EditedOn mismatch for test case")
+ assert.Equal(t, n2Record.Body, n2.Body, "n2 Body mismatch for test case")
+ assert.Equal(t, n2Record.Deleted, n2.Deleted, "n2 Deleted mismatch for test case")
+ assert.Equal(t, n2Record.Dirty, n2.Dirty, "n2 Dirty mismatch for test case")
})
t.Run("local copy has at least one note that is dirty", func(t *testing.T) {
b1UUID := utils.GenerateUUID()
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
-
- testutils.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
- testutils.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, true)
+ database.MustExec(t, "inserting b1 for test case %d", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
+ database.MustExec(t, "inserting n1 for test case %d", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, true)
// execute
tx, err := db.Begin()
@@ -585,44 +564,42 @@ func TestSyncDeleteBook(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes for test case", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books for test case", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 1, "note count mismatch for test case")
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch for test case")
+ database.MustScan(t, "counting notes for test case", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books for test case", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ assert.Equalf(t, noteCount, 1, "note count mismatch for test case")
+ assert.Equalf(t, bookCount, 1, "book count mismatch for test case")
- var b1Record core.Book
- testutils.MustScan(t, "getting b1 for test case",
+ var b1Record database.Book
+ database.MustScan(t, "getting b1 for test case",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", b1UUID),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
- var n1Record core.Note
- testutils.MustScan(t, "getting n1 for test case",
+ var n1Record database.Note
+ database.MustScan(t, "getting n1 for test case",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, body,deleted, dirty FROM notes WHERE uuid = ?", "n1-uuid"),
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.Body, &n1Record.Deleted, &n1Record.Dirty)
- testutils.AssertEqual(t, b1Record.UUID, b1UUID, "b1 UUID mismatch for test case")
- testutils.AssertEqual(t, b1Record.Label, "b1-label", "b1 Label mismatch for test case")
- testutils.AssertEqual(t, b1Record.Dirty, true, "b1 Dirty mismatch for test case")
+ assert.Equal(t, b1Record.UUID, b1UUID, "b1 UUID mismatch for test case")
+ assert.Equal(t, b1Record.Label, "b1-label", "b1 Label mismatch for test case")
+ assert.Equal(t, b1Record.Dirty, true, "b1 Dirty mismatch for test case")
- testutils.AssertEqual(t, n1Record.UUID, "n1-uuid", "n1 UUID mismatch for test case")
- testutils.AssertEqual(t, n1Record.BookUUID, b1UUID, "n1 BookUUID mismatch for test case")
- testutils.AssertEqual(t, n1Record.USN, 10, "n1 USN mismatch for test case")
- testutils.AssertEqual(t, n1Record.AddedOn, int64(1541108743), "n1 AddedOn mismatch for test case")
- testutils.AssertEqual(t, n1Record.Body, "n1 body", "n1 Body mismatch for test case")
- testutils.AssertEqual(t, n1Record.Deleted, false, "n1 Deleted mismatch for test case")
- testutils.AssertEqual(t, n1Record.Dirty, true, "n1 Dirty mismatch for test case")
+ assert.Equal(t, n1Record.UUID, "n1-uuid", "n1 UUID mismatch for test case")
+ assert.Equal(t, n1Record.BookUUID, b1UUID, "n1 BookUUID mismatch for test case")
+ assert.Equal(t, n1Record.USN, 10, "n1 USN mismatch for test case")
+ assert.Equal(t, n1Record.AddedOn, int64(1541108743), "n1 AddedOn mismatch for test case")
+ assert.Equal(t, n1Record.Body, "n1 body", "n1 Body mismatch for test case")
+ assert.Equal(t, n1Record.Deleted, false, "n1 Deleted mismatch for test case")
+ assert.Equal(t, n1Record.Dirty, true, "n1 Dirty mismatch for test case")
})
}
func TestFullSyncNote(t *testing.T) {
t.Run("exists on server only", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
// execute
tx, err := db.Begin()
@@ -649,25 +626,25 @@ func TestFullSyncNote(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 1, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch")
+ assert.Equalf(t, noteCount, 1, "note count mismatch")
+ assert.Equalf(t, bookCount, 1, "book count mismatch")
- var n1 core.Note
- testutils.MustScan(t, "getting n1",
+ var n1 database.Note
+ database.MustScan(t, "getting n1",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Deleted, &n1.Dirty)
- testutils.AssertEqual(t, n1.UUID, n.UUID, "n1 UUID mismatch")
- testutils.AssertEqual(t, n1.BookUUID, n.BookUUID, "n1 BookUUID mismatch")
- testutils.AssertEqual(t, n1.USN, n.USN, "n1 USN mismatch")
- testutils.AssertEqual(t, n1.AddedOn, n.AddedOn, "n1 AddedOn mismatch")
- testutils.AssertEqual(t, n1.EditedOn, n.EditedOn, "n1 EditedOn mismatch")
- testutils.AssertEqual(t, n1.Body, n.Body, "n1 Body mismatch")
- testutils.AssertEqual(t, n1.Deleted, n.Deleted, "n1 Deleted mismatch")
- testutils.AssertEqual(t, n1.Dirty, false, "n1 Dirty mismatch")
+ assert.Equal(t, n1.UUID, n.UUID, "n1 UUID mismatch")
+ assert.Equal(t, n1.BookUUID, n.BookUUID, "n1 BookUUID mismatch")
+ assert.Equal(t, n1.USN, n.USN, "n1 USN mismatch")
+ assert.Equal(t, n1.AddedOn, n.AddedOn, "n1 AddedOn mismatch")
+ assert.Equal(t, n1.EditedOn, n.EditedOn, "n1 EditedOn mismatch")
+ assert.Equal(t, n1.Body, n.Body, "n1 Body mismatch")
+ assert.Equal(t, n1.Deleted, n.Deleted, "n1 Deleted mismatch")
+ assert.Equal(t, n1.Dirty, false, "n1 Dirty mismatch")
})
t.Run("exists on server and client", func(t *testing.T) {
@@ -850,16 +827,14 @@ n1 body edited
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
-
- testutils.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
- testutils.MustExec(t, fmt.Sprintf("inserting b2 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "b2-label")
- testutils.MustExec(t, fmt.Sprintf("inserting conflitcs book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", conflictBookUUID, "conflicts")
+ database.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
+ database.MustExec(t, fmt.Sprintf("inserting b2 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "b2-label")
+ database.MustExec(t, fmt.Sprintf("inserting conflitcs book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", conflictBookUUID, "conflicts")
n1UUID := utils.GenerateUUID()
- testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, tc.clientBookUUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientBody, tc.clientDeleted, tc.clientDirty)
+ database.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, tc.clientBookUUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientBody, tc.clientDeleted, tc.clientDirty)
// execute
tx, err := db.Begin()
@@ -887,25 +862,25 @@ n1 body edited
// test
var noteCount, bookCount int
- testutils.MustScan(t, fmt.Sprintf("counting notes for test case %d", idx), db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, fmt.Sprintf("counting books for test case %d", idx), db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, fmt.Sprintf("counting notes for test case %d", idx), db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, fmt.Sprintf("counting books for test case %d", idx), db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 1, fmt.Sprintf("note count mismatch for test case %d", idx))
- testutils.AssertEqualf(t, bookCount, 3, fmt.Sprintf("book count mismatch for test case %d", idx))
+ assert.Equalf(t, noteCount, 1, fmt.Sprintf("note count mismatch for test case %d", idx))
+ assert.Equalf(t, bookCount, 3, fmt.Sprintf("book count mismatch for test case %d", idx))
- var n1 core.Note
- testutils.MustScan(t, fmt.Sprintf("getting n1 for test case %d", idx),
+ var n1 database.Note
+ database.MustScan(t, fmt.Sprintf("getting n1 for test case %d", idx),
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Deleted, &n1.Dirty)
- testutils.AssertEqual(t, n1.UUID, n.UUID, fmt.Sprintf("n1 UUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.BookUUID, tc.expectedBookUUID, fmt.Sprintf("n1 BookUUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.USN, tc.expectedUSN, fmt.Sprintf("n1 USN mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.AddedOn, tc.expectedAddedOn, fmt.Sprintf("n1 AddedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.EditedOn, tc.expectedEditedOn, fmt.Sprintf("n1 EditedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.Body, tc.expectedBody, fmt.Sprintf("n1 Body mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.Deleted, tc.expectedDeleted, fmt.Sprintf("n1 Deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.Dirty, tc.expectedDirty, fmt.Sprintf("n1 Dirty mismatch for test case %d", idx))
+ assert.Equal(t, n1.UUID, n.UUID, fmt.Sprintf("n1 UUID mismatch for test case %d", idx))
+ assert.Equal(t, n1.BookUUID, tc.expectedBookUUID, fmt.Sprintf("n1 BookUUID mismatch for test case %d", idx))
+ assert.Equal(t, n1.USN, tc.expectedUSN, fmt.Sprintf("n1 USN mismatch for test case %d", idx))
+ assert.Equal(t, n1.AddedOn, tc.expectedAddedOn, fmt.Sprintf("n1 AddedOn mismatch for test case %d", idx))
+ assert.Equal(t, n1.EditedOn, tc.expectedEditedOn, fmt.Sprintf("n1 EditedOn mismatch for test case %d", idx))
+ assert.Equal(t, n1.Body, tc.expectedBody, fmt.Sprintf("n1 Body mismatch for test case %d", idx))
+ assert.Equal(t, n1.Deleted, tc.expectedDeleted, fmt.Sprintf("n1 Deleted mismatch for test case %d", idx))
+ assert.Equal(t, n1.Dirty, tc.expectedDirty, fmt.Sprintf("n1 Dirty mismatch for test case %d", idx))
}()
}
})
@@ -914,13 +889,11 @@ n1 body edited
func TestFullSyncBook(t *testing.T) {
t.Run("exists on server only", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b1UUID, 555, "b1-label", true, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b1UUID, 555, "b1-label", true, false)
// execute
tx, err := db.Begin()
@@ -946,31 +919,31 @@ func TestFullSyncBook(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 2, "book count mismatch")
+ assert.Equalf(t, noteCount, 0, "note count mismatch")
+ assert.Equalf(t, bookCount, 2, "book count mismatch")
- var b1, b2 core.Book
- testutils.MustScan(t, "getting b1",
+ var b1, b2 database.Book
+ database.MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, usn, label, dirty, deleted FROM books WHERE uuid = ?", b1UUID),
&b1.UUID, &b1.USN, &b1.Label, &b1.Dirty, &b1.Deleted)
- testutils.MustScan(t, "getting b2",
+ database.MustScan(t, "getting b2",
db.QueryRow("SELECT uuid, usn, label, dirty, deleted FROM books WHERE uuid = ?", b2UUID),
&b2.UUID, &b2.USN, &b2.Label, &b2.Dirty, &b2.Deleted)
- testutils.AssertEqual(t, b1.UUID, b1UUID, "b1 UUID mismatch")
- testutils.AssertEqual(t, b1.USN, 555, "b1 USN mismatch")
- testutils.AssertEqual(t, b1.Label, "b1-label", "b1 Label mismatch")
- testutils.AssertEqual(t, b1.Dirty, true, "b1 Dirty mismatch")
- testutils.AssertEqual(t, b1.Deleted, false, "b1 Deleted mismatch")
+ assert.Equal(t, b1.UUID, b1UUID, "b1 UUID mismatch")
+ assert.Equal(t, b1.USN, 555, "b1 USN mismatch")
+ assert.Equal(t, b1.Label, "b1-label", "b1 Label mismatch")
+ assert.Equal(t, b1.Dirty, true, "b1 Dirty mismatch")
+ assert.Equal(t, b1.Deleted, false, "b1 Deleted mismatch")
- testutils.AssertEqual(t, b2.UUID, b2UUID, "b2 UUID mismatch")
- testutils.AssertEqual(t, b2.USN, b.USN, "b2 USN mismatch")
- testutils.AssertEqual(t, b2.Label, b.Label, "b2 Label mismatch")
- testutils.AssertEqual(t, b2.Dirty, false, "b2 Dirty mismatch")
- testutils.AssertEqual(t, b2.Deleted, b.Deleted, "b2 Deleted mismatch")
+ assert.Equal(t, b2.UUID, b2UUID, "b2 UUID mismatch")
+ assert.Equal(t, b2.USN, b.USN, "b2 USN mismatch")
+ assert.Equal(t, b2.Label, b.Label, "b2 Label mismatch")
+ assert.Equal(t, b2.Dirty, false, "b2 Dirty mismatch")
+ assert.Equal(t, b2.Deleted, b.Deleted, "b2 Deleted mismatch")
})
t.Run("exists on server and client", func(t *testing.T) {
@@ -1055,13 +1028,11 @@ func TestFullSyncBook(t *testing.T) {
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b1UUID, tc.clientUSN, tc.clientLabel, tc.clientDirty, tc.clientDeleted)
+ database.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b1UUID, tc.clientUSN, tc.clientLabel, tc.clientDirty, tc.clientDeleted)
// execute
tx, err := db.Begin()
@@ -1086,22 +1057,22 @@ func TestFullSyncBook(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, fmt.Sprintf("counting notes for test case %d", idx), db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, fmt.Sprintf("counting books for test case %d", idx), db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, fmt.Sprintf("counting notes for test case %d", idx), db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, fmt.Sprintf("counting books for test case %d", idx), db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, fmt.Sprintf("note count mismatch for test case %d", idx))
- testutils.AssertEqualf(t, bookCount, 1, fmt.Sprintf("book count mismatch for test case %d", idx))
+ assert.Equalf(t, noteCount, 0, fmt.Sprintf("note count mismatch for test case %d", idx))
+ assert.Equalf(t, bookCount, 1, fmt.Sprintf("book count mismatch for test case %d", idx))
- var b1 core.Book
- testutils.MustScan(t, "getting b1",
+ var b1 database.Book
+ database.MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, usn, label, dirty, deleted FROM books WHERE uuid = ?", b1UUID),
&b1.UUID, &b1.USN, &b1.Label, &b1.Dirty, &b1.Deleted)
- testutils.AssertEqual(t, b1.UUID, b1UUID, fmt.Sprintf("b1 UUID mismatch for idx %d", idx))
- testutils.AssertEqual(t, b1.USN, tc.expectedUSN, fmt.Sprintf("b1 USN mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1.Label, tc.expectedLabel, fmt.Sprintf("b1 Label mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1.Dirty, tc.clientDirty, fmt.Sprintf("b1 Dirty mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1.Deleted, tc.expectedDeleted, fmt.Sprintf("b1 Deleted mismatch for test case %d", idx))
+ assert.Equal(t, b1.UUID, b1UUID, fmt.Sprintf("b1 UUID mismatch for idx %d", idx))
+ assert.Equal(t, b1.USN, tc.expectedUSN, fmt.Sprintf("b1 USN mismatch for test case %d", idx))
+ assert.Equal(t, b1.Label, tc.expectedLabel, fmt.Sprintf("b1 Label mismatch for test case %d", idx))
+ assert.Equal(t, b1.Dirty, tc.clientDirty, fmt.Sprintf("b1 Dirty mismatch for test case %d", idx))
+ assert.Equal(t, b1.Deleted, tc.expectedDeleted, fmt.Sprintf("b1 Deleted mismatch for test case %d", idx))
}()
}
})
@@ -1110,13 +1081,11 @@ func TestFullSyncBook(t *testing.T) {
func TestStepSyncNote(t *testing.T) {
t.Run("exists on server only", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
// execute
tx, err := db.Begin()
@@ -1143,25 +1112,25 @@ func TestStepSyncNote(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 1, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch")
+ assert.Equalf(t, noteCount, 1, "note count mismatch")
+ assert.Equalf(t, bookCount, 1, "book count mismatch")
- var n1 core.Note
- testutils.MustScan(t, "getting n1",
+ var n1 database.Note
+ database.MustScan(t, "getting n1",
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Deleted, &n1.Dirty)
- testutils.AssertEqual(t, n1.UUID, n.UUID, "n1 UUID mismatch")
- testutils.AssertEqual(t, n1.BookUUID, n.BookUUID, "n1 BookUUID mismatch")
- testutils.AssertEqual(t, n1.USN, n.USN, "n1 USN mismatch")
- testutils.AssertEqual(t, n1.AddedOn, n.AddedOn, "n1 AddedOn mismatch")
- testutils.AssertEqual(t, n1.EditedOn, n.EditedOn, "n1 EditedOn mismatch")
- testutils.AssertEqual(t, n1.Body, n.Body, "n1 Body mismatch")
- testutils.AssertEqual(t, n1.Deleted, n.Deleted, "n1 Deleted mismatch")
- testutils.AssertEqual(t, n1.Dirty, false, "n1 Dirty mismatch")
+ assert.Equal(t, n1.UUID, n.UUID, "n1 UUID mismatch")
+ assert.Equal(t, n1.BookUUID, n.BookUUID, "n1 BookUUID mismatch")
+ assert.Equal(t, n1.USN, n.USN, "n1 USN mismatch")
+ assert.Equal(t, n1.AddedOn, n.AddedOn, "n1 AddedOn mismatch")
+ assert.Equal(t, n1.EditedOn, n.EditedOn, "n1 EditedOn mismatch")
+ assert.Equal(t, n1.Body, n.Body, "n1 Body mismatch")
+ assert.Equal(t, n1.Deleted, n.Deleted, "n1 Deleted mismatch")
+ assert.Equal(t, n1.Dirty, false, "n1 Dirty mismatch")
})
t.Run("exists on server and client", func(t *testing.T) {
@@ -1270,16 +1239,14 @@ n1 body edited
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
-
- testutils.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
- testutils.MustExec(t, fmt.Sprintf("inserting b2 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "b2-label")
- testutils.MustExec(t, fmt.Sprintf("inserting conflitcs book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", conflictBookUUID, "conflicts")
+ database.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1-label")
+ database.MustExec(t, fmt.Sprintf("inserting b2 for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "b2-label")
+ database.MustExec(t, fmt.Sprintf("inserting conflitcs book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", conflictBookUUID, "conflicts")
n1UUID := utils.GenerateUUID()
- testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, tc.clientBookUUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientBody, tc.clientDeleted, tc.clientDirty)
+ database.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, tc.clientBookUUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientBody, tc.clientDeleted, tc.clientDirty)
// execute
tx, err := db.Begin()
@@ -1307,25 +1274,25 @@ n1 body edited
// test
var noteCount, bookCount int
- testutils.MustScan(t, fmt.Sprintf("counting notes for test case %d", idx), db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, fmt.Sprintf("counting books for test case %d", idx), db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, fmt.Sprintf("counting notes for test case %d", idx), db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, fmt.Sprintf("counting books for test case %d", idx), db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 1, fmt.Sprintf("note count mismatch for test case %d", idx))
- testutils.AssertEqualf(t, bookCount, 3, fmt.Sprintf("book count mismatch for test case %d", idx))
+ assert.Equalf(t, noteCount, 1, fmt.Sprintf("note count mismatch for test case %d", idx))
+ assert.Equalf(t, bookCount, 3, fmt.Sprintf("book count mismatch for test case %d", idx))
- var n1 core.Note
- testutils.MustScan(t, fmt.Sprintf("getting n1 for test case %d", idx),
+ var n1 database.Note
+ database.MustScan(t, fmt.Sprintf("getting n1 for test case %d", idx),
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", n.UUID),
&n1.UUID, &n1.BookUUID, &n1.USN, &n1.AddedOn, &n1.EditedOn, &n1.Body, &n1.Deleted, &n1.Dirty)
- testutils.AssertEqual(t, n1.UUID, n.UUID, fmt.Sprintf("n1 UUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.BookUUID, tc.expectedBookUUID, fmt.Sprintf("n1 BookUUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.USN, tc.expectedUSN, fmt.Sprintf("n1 USN mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.AddedOn, tc.expectedAddedOn, fmt.Sprintf("n1 AddedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.EditedOn, tc.expectedEditedOn, fmt.Sprintf("n1 EditedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.Body, tc.expectedBody, fmt.Sprintf("n1 Body mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.Deleted, tc.expectedDeleted, fmt.Sprintf("n1 Deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1.Dirty, tc.expectedDirty, fmt.Sprintf("n1 Dirty mismatch for test case %d", idx))
+ assert.Equal(t, n1.UUID, n.UUID, fmt.Sprintf("n1 UUID mismatch for test case %d", idx))
+ assert.Equal(t, n1.BookUUID, tc.expectedBookUUID, fmt.Sprintf("n1 BookUUID mismatch for test case %d", idx))
+ assert.Equal(t, n1.USN, tc.expectedUSN, fmt.Sprintf("n1 USN mismatch for test case %d", idx))
+ assert.Equal(t, n1.AddedOn, tc.expectedAddedOn, fmt.Sprintf("n1 AddedOn mismatch for test case %d", idx))
+ assert.Equal(t, n1.EditedOn, tc.expectedEditedOn, fmt.Sprintf("n1 EditedOn mismatch for test case %d", idx))
+ assert.Equal(t, n1.Body, tc.expectedBody, fmt.Sprintf("n1 Body mismatch for test case %d", idx))
+ assert.Equal(t, n1.Deleted, tc.expectedDeleted, fmt.Sprintf("n1 Deleted mismatch for test case %d", idx))
+ assert.Equal(t, n1.Dirty, tc.expectedDirty, fmt.Sprintf("n1 Dirty mismatch for test case %d", idx))
}()
}
})
@@ -1334,13 +1301,11 @@ n1 body edited
func TestStepSyncBook(t *testing.T) {
t.Run("exists on server only", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b1UUID, 555, "b1-label", true, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b1UUID, 555, "b1-label", true, false)
// execute
tx, err := db.Begin()
@@ -1366,31 +1331,31 @@ func TestStepSyncBook(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 2, "book count mismatch")
+ assert.Equalf(t, noteCount, 0, "note count mismatch")
+ assert.Equalf(t, bookCount, 2, "book count mismatch")
- var b1, b2 core.Book
- testutils.MustScan(t, "getting b1",
+ var b1, b2 database.Book
+ database.MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, usn, label, dirty, deleted FROM books WHERE uuid = ?", b1UUID),
&b1.UUID, &b1.USN, &b1.Label, &b1.Dirty, &b1.Deleted)
- testutils.MustScan(t, "getting b2",
+ database.MustScan(t, "getting b2",
db.QueryRow("SELECT uuid, usn, label, dirty, deleted FROM books WHERE uuid = ?", b2UUID),
&b2.UUID, &b2.USN, &b2.Label, &b2.Dirty, &b2.Deleted)
- testutils.AssertEqual(t, b1.UUID, b1UUID, "b1 UUID mismatch")
- testutils.AssertEqual(t, b1.USN, 555, "b1 USN mismatch")
- testutils.AssertEqual(t, b1.Label, "b1-label", "b1 Label mismatch")
- testutils.AssertEqual(t, b1.Dirty, true, "b1 Dirty mismatch")
- testutils.AssertEqual(t, b1.Deleted, false, "b1 Deleted mismatch")
+ assert.Equal(t, b1.UUID, b1UUID, "b1 UUID mismatch")
+ assert.Equal(t, b1.USN, 555, "b1 USN mismatch")
+ assert.Equal(t, b1.Label, "b1-label", "b1 Label mismatch")
+ assert.Equal(t, b1.Dirty, true, "b1 Dirty mismatch")
+ assert.Equal(t, b1.Deleted, false, "b1 Deleted mismatch")
- testutils.AssertEqual(t, b2.UUID, b2UUID, "b2 UUID mismatch")
- testutils.AssertEqual(t, b2.USN, b.USN, "b2 USN mismatch")
- testutils.AssertEqual(t, b2.Label, b.Label, "b2 Label mismatch")
- testutils.AssertEqual(t, b2.Dirty, false, "b2 Dirty mismatch")
- testutils.AssertEqual(t, b2.Deleted, b.Deleted, "b2 Deleted mismatch")
+ assert.Equal(t, b2.UUID, b2UUID, "b2 UUID mismatch")
+ assert.Equal(t, b2.USN, b.USN, "b2 USN mismatch")
+ assert.Equal(t, b2.Label, b.Label, "b2 Label mismatch")
+ assert.Equal(t, b2.Dirty, false, "b2 Dirty mismatch")
+ assert.Equal(t, b2.Deleted, b.Deleted, "b2 Deleted mismatch")
})
t.Run("exists on server and client", func(t *testing.T) {
@@ -1459,15 +1424,13 @@ func TestStepSyncBook(t *testing.T) {
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b1UUID, tc.clientUSN, tc.clientLabel, tc.clientDirty, tc.clientDeleted)
+ database.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b1UUID, tc.clientUSN, tc.clientLabel, tc.clientDirty, tc.clientDeleted)
b2UUID := utils.GenerateUUID()
- testutils.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b2UUID, 2, tc.anotherBookLabel, false, false)
+ database.MustExec(t, fmt.Sprintf("inserting book for test case %d", idx), db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b2UUID, 2, tc.anotherBookLabel, false, false)
// execute
tx, err := db.Begin()
@@ -1492,31 +1455,31 @@ func TestStepSyncBook(t *testing.T) {
// test
var noteCount, bookCount int
- testutils.MustScan(t, fmt.Sprintf("counting notes for test case %d", idx), db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, fmt.Sprintf("counting books for test case %d", idx), db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, fmt.Sprintf("counting notes for test case %d", idx), db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, fmt.Sprintf("counting books for test case %d", idx), db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, fmt.Sprintf("note count mismatch for test case %d", idx))
- testutils.AssertEqualf(t, bookCount, 2, fmt.Sprintf("book count mismatch for test case %d", idx))
+ assert.Equalf(t, noteCount, 0, fmt.Sprintf("note count mismatch for test case %d", idx))
+ assert.Equalf(t, bookCount, 2, fmt.Sprintf("book count mismatch for test case %d", idx))
- var b1Record, b2Record core.Book
- testutils.MustScan(t, "getting b1Record",
+ var b1Record, b2Record database.Book
+ database.MustScan(t, "getting b1Record",
db.QueryRow("SELECT uuid, usn, label, dirty, deleted FROM books WHERE uuid = ?", b1UUID),
&b1Record.UUID, &b1Record.USN, &b1Record.Label, &b1Record.Dirty, &b1Record.Deleted)
- testutils.MustScan(t, "getting b2Record",
+ database.MustScan(t, "getting b2Record",
db.QueryRow("SELECT uuid, usn, label, dirty, deleted FROM books WHERE uuid = ?", b2UUID),
&b2Record.UUID, &b2Record.USN, &b2Record.Label, &b2Record.Dirty, &b2Record.Deleted)
- testutils.AssertEqual(t, b1Record.UUID, b1UUID, fmt.Sprintf("b1Record UUID mismatch for idx %d", idx))
- testutils.AssertEqual(t, b1Record.USN, tc.expectedUSN, fmt.Sprintf("b1Record USN mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1Record.Label, tc.expectedLabel, fmt.Sprintf("b1Record Label mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1Record.Dirty, tc.clientDirty, fmt.Sprintf("b1Record Dirty mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1Record.Deleted, tc.expectedDeleted, fmt.Sprintf("b1Record Deleted mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.UUID, b1UUID, fmt.Sprintf("b1Record UUID mismatch for idx %d", idx))
+ assert.Equal(t, b1Record.USN, tc.expectedUSN, fmt.Sprintf("b1Record USN mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.Label, tc.expectedLabel, fmt.Sprintf("b1Record Label mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.Dirty, tc.clientDirty, fmt.Sprintf("b1Record Dirty mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.Deleted, tc.expectedDeleted, fmt.Sprintf("b1Record Deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.UUID, b2UUID, fmt.Sprintf("b2Record UUID mismatch for idx %d", idx))
- testutils.AssertEqual(t, b2Record.USN, 2, fmt.Sprintf("b2Record USN mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.Label, tc.expectedAnotherBookLabel, fmt.Sprintf("b2Record Label mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.Dirty, tc.expectedAnotherBookDirty, fmt.Sprintf("b2Record Dirty mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.Deleted, false, fmt.Sprintf("b2Record Deleted mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.UUID, b2UUID, fmt.Sprintf("b2Record UUID mismatch for idx %d", idx))
+ assert.Equal(t, b2Record.USN, 2, fmt.Sprintf("b2Record USN mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.Label, tc.expectedAnotherBookLabel, fmt.Sprintf("b2Record Label mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.Dirty, tc.expectedAnotherBookDirty, fmt.Sprintf("b2Record Dirty mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.Deleted, false, fmt.Sprintf("b2Record Deleted mismatch for test case %d", idx))
}()
}
})
@@ -1525,10 +1488,8 @@ func TestStepSyncBook(t *testing.T) {
func TestMergeBook(t *testing.T) {
t.Run("insert, no duplicates", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
// test
tx, err := db.Begin()
@@ -1553,30 +1514,27 @@ func TestMergeBook(t *testing.T) {
// execute
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch")
+ assert.Equalf(t, noteCount, 0, "note count mismatch")
+ assert.Equalf(t, bookCount, 1, "book count mismatch")
- var b1Record core.Book
- testutils.MustScan(t, "getting b1",
+ var b1Record database.Book
+ database.MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b1-uuid"),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
- testutils.AssertEqual(t, b1Record.UUID, b1.UUID, "b1 UUID mismatch")
- testutils.AssertEqual(t, b1Record.Label, b1.Label, "b1 Label mismatch")
- testutils.AssertEqual(t, b1Record.USN, b1.USN, "b1 USN mismatch")
+ assert.Equal(t, b1Record.UUID, b1.UUID, "b1 UUID mismatch")
+ assert.Equal(t, b1Record.Label, b1.Label, "b1 Label mismatch")
+ assert.Equal(t, b1Record.USN, b1.USN, "b1 USN mismatch")
})
t.Run("insert, 1 duplicate", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
-
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b1-uuid", 1, "foo", false, false)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b1-uuid", 1, "foo", false, false)
// test
tx, err := db.Begin()
@@ -1601,39 +1559,37 @@ func TestMergeBook(t *testing.T) {
// execute
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 2, "book count mismatch")
+ assert.Equalf(t, noteCount, 0, "note count mismatch")
+ assert.Equalf(t, bookCount, 2, "book count mismatch")
- var b1Record, b2Record core.Book
- testutils.MustScan(t, "getting b1",
+ var b1Record, b2Record database.Book
+ database.MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b1-uuid"),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
- testutils.MustScan(t, "getting b2",
+ database.MustScan(t, "getting b2",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b2-uuid"),
&b2Record.UUID, &b2Record.Label, &b2Record.USN, &b2Record.Dirty)
- testutils.AssertEqual(t, b1Record.Label, "foo_2", "b1 Label mismatch")
- testutils.AssertEqual(t, b1Record.USN, 1, "b1 USN mismatch")
- testutils.AssertEqual(t, b1Record.Dirty, true, "b1 should have been marked dirty")
+ assert.Equal(t, b1Record.Label, "foo_2", "b1 Label mismatch")
+ assert.Equal(t, b1Record.USN, 1, "b1 USN mismatch")
+ assert.Equal(t, b1Record.Dirty, true, "b1 should have been marked dirty")
- testutils.AssertEqual(t, b2Record.Label, "foo", "b2 Label mismatch")
- testutils.AssertEqual(t, b2Record.USN, 12, "b2 USN mismatch")
- testutils.AssertEqual(t, b2Record.Dirty, false, "b2 Dirty mismatch")
+ assert.Equal(t, b2Record.Label, "foo", "b2 Label mismatch")
+ assert.Equal(t, b2Record.USN, 12, "b2 USN mismatch")
+ assert.Equal(t, b2Record.Dirty, false, "b2 Dirty mismatch")
})
t.Run("insert, 3 duplicates", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
-
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b1-uuid", 1, "foo", false, false)
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b2-uuid", 2, "foo_2", true, false)
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b3-uuid", 3, "foo_3", false, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b1-uuid", 1, "foo", false, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b2-uuid", 2, "foo_2", true, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b3-uuid", 3, "foo_3", false, false)
// test
tx, err := db.Begin()
@@ -1658,49 +1614,47 @@ func TestMergeBook(t *testing.T) {
// execute
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 4, "book count mismatch")
+ assert.Equalf(t, noteCount, 0, "note count mismatch")
+ assert.Equalf(t, bookCount, 4, "book count mismatch")
- var b1Record, b2Record, b3Record, b4Record core.Book
- testutils.MustScan(t, "getting b1",
+ var b1Record, b2Record, b3Record, b4Record database.Book
+ database.MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b1-uuid"),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
- testutils.MustScan(t, "getting b2",
+ database.MustScan(t, "getting b2",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b2-uuid"),
&b2Record.UUID, &b2Record.Label, &b2Record.USN, &b2Record.Dirty)
- testutils.MustScan(t, "getting b3",
+ database.MustScan(t, "getting b3",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b3-uuid"),
&b3Record.UUID, &b3Record.Label, &b3Record.USN, &b3Record.Dirty)
- testutils.MustScan(t, "getting b4",
+ database.MustScan(t, "getting b4",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b4-uuid"),
&b4Record.UUID, &b4Record.Label, &b4Record.USN, &b4Record.Dirty)
- testutils.AssertEqual(t, b1Record.Label, "foo_4", "b1 Label mismatch")
- testutils.AssertEqual(t, b1Record.USN, 1, "b1 USN mismatch")
- testutils.AssertEqual(t, b1Record.Dirty, true, "b1 Dirty mismatch")
+ assert.Equal(t, b1Record.Label, "foo_4", "b1 Label mismatch")
+ assert.Equal(t, b1Record.USN, 1, "b1 USN mismatch")
+ assert.Equal(t, b1Record.Dirty, true, "b1 Dirty mismatch")
- testutils.AssertEqual(t, b2Record.Label, "foo_2", "b2 Label mismatch")
- testutils.AssertEqual(t, b2Record.USN, 2, "b2 USN mismatch")
- testutils.AssertEqual(t, b2Record.Dirty, true, "b2 Dirty mismatch")
+ assert.Equal(t, b2Record.Label, "foo_2", "b2 Label mismatch")
+ assert.Equal(t, b2Record.USN, 2, "b2 USN mismatch")
+ assert.Equal(t, b2Record.Dirty, true, "b2 Dirty mismatch")
- testutils.AssertEqual(t, b3Record.Label, "foo_3", "b3 Label mismatch")
- testutils.AssertEqual(t, b3Record.USN, 3, "b3 USN mismatch")
- testutils.AssertEqual(t, b3Record.Dirty, false, "b3 Dirty mismatch")
+ assert.Equal(t, b3Record.Label, "foo_3", "b3 Label mismatch")
+ assert.Equal(t, b3Record.USN, 3, "b3 USN mismatch")
+ assert.Equal(t, b3Record.Dirty, false, "b3 Dirty mismatch")
- testutils.AssertEqual(t, b4Record.Label, "foo", "b4 Label mismatch")
- testutils.AssertEqual(t, b4Record.USN, 12, "b4 USN mismatch")
- testutils.AssertEqual(t, b4Record.Dirty, false, "b4 Dirty mismatch")
+ assert.Equal(t, b4Record.Label, "foo", "b4 Label mismatch")
+ assert.Equal(t, b4Record.USN, 12, "b4 USN mismatch")
+ assert.Equal(t, b4Record.Dirty, false, "b4 Dirty mismatch")
})
t.Run("update, no duplicates", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
// test
tx, err := db.Begin()
@@ -1709,7 +1663,7 @@ func TestMergeBook(t *testing.T) {
}
b1UUID := utils.GenerateUUID()
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b1UUID, 1, "b1-label", false, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", b1UUID, 1, "b1-label", false, false)
b1 := client.SyncFragBook{
UUID: b1UUID,
@@ -1728,31 +1682,29 @@ func TestMergeBook(t *testing.T) {
// execute
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch")
+ assert.Equalf(t, noteCount, 0, "note count mismatch")
+ assert.Equalf(t, bookCount, 1, "book count mismatch")
- var b1Record core.Book
- testutils.MustScan(t, "getting b1",
+ var b1Record database.Book
+ database.MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", b1UUID),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
- testutils.AssertEqual(t, b1Record.UUID, b1UUID, "b1 UUID mismatch")
- testutils.AssertEqual(t, b1Record.Label, "b1-label-edited", "b1 Label mismatch")
- testutils.AssertEqual(t, b1Record.USN, 12, "b1 USN mismatch")
+ assert.Equal(t, b1Record.UUID, b1UUID, "b1 UUID mismatch")
+ assert.Equal(t, b1Record.Label, "b1-label-edited", "b1 Label mismatch")
+ assert.Equal(t, b1Record.USN, 12, "b1 USN mismatch")
})
t.Run("update, 1 duplicate", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
-
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b1-uuid", 1, "foo", false, false)
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b2-uuid", 2, "bar", false, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b1-uuid", 1, "foo", false, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b2-uuid", 2, "bar", false, false)
// test
tx, err := db.Begin()
@@ -1777,40 +1729,38 @@ func TestMergeBook(t *testing.T) {
// execute
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 2, "book count mismatch")
+ assert.Equalf(t, noteCount, 0, "note count mismatch")
+ assert.Equalf(t, bookCount, 2, "book count mismatch")
- var b1Record, b2Record core.Book
- testutils.MustScan(t, "getting b1",
+ var b1Record, b2Record database.Book
+ database.MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b1-uuid"),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
- testutils.MustScan(t, "getting b2",
+ database.MustScan(t, "getting b2",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b2-uuid"),
&b2Record.UUID, &b2Record.Label, &b2Record.USN, &b2Record.Dirty)
- testutils.AssertEqual(t, b1Record.Label, "bar", "b1 Label mismatch")
- testutils.AssertEqual(t, b1Record.USN, 12, "b1 USN mismatch")
- testutils.AssertEqual(t, b1Record.Dirty, false, "b1 Dirty mismatch")
+ assert.Equal(t, b1Record.Label, "bar", "b1 Label mismatch")
+ assert.Equal(t, b1Record.USN, 12, "b1 USN mismatch")
+ assert.Equal(t, b1Record.Dirty, false, "b1 Dirty mismatch")
- testutils.AssertEqual(t, b2Record.Label, "bar_2", "b2 Label mismatch")
- testutils.AssertEqual(t, b2Record.USN, 2, "b2 USN mismatch")
- testutils.AssertEqual(t, b2Record.Dirty, true, "b2 Dirty mismatch")
+ assert.Equal(t, b2Record.Label, "bar_2", "b2 Label mismatch")
+ assert.Equal(t, b2Record.USN, 2, "b2 USN mismatch")
+ assert.Equal(t, b2Record.Dirty, true, "b2 Dirty mismatch")
})
t.Run("update, 3 duplicate", func(t *testing.T) {
// set uj
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, dbPath, nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
-
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b1-uuid", 1, "foo", false, false)
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b2-uuid", 2, "bar", false, false)
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b3-uuid", 3, "bar_2", true, false)
- testutils.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b4-uuid", 4, "bar_3", false, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b1-uuid", 1, "foo", false, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b2-uuid", 2, "bar", false, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b3-uuid", 3, "bar_2", true, false)
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, usn, label, dirty, deleted) VALUES (?, ?, ?, ?, ?)", "b4-uuid", 4, "bar_3", false, false)
// test
tx, err := db.Begin()
@@ -1835,54 +1785,54 @@ func TestMergeBook(t *testing.T) {
// execute
var noteCount, bookCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 0, "note count mismatch")
- testutils.AssertEqualf(t, bookCount, 4, "book count mismatch")
+ assert.Equalf(t, noteCount, 0, "note count mismatch")
+ assert.Equalf(t, bookCount, 4, "book count mismatch")
- var b1Record, b2Record, b3Record, b4Record core.Book
- testutils.MustScan(t, "getting b1",
+ var b1Record, b2Record, b3Record, b4Record database.Book
+ database.MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b1-uuid"),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
- testutils.MustScan(t, "getting b2",
+ database.MustScan(t, "getting b2",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b2-uuid"),
&b2Record.UUID, &b2Record.Label, &b2Record.USN, &b2Record.Dirty)
- testutils.MustScan(t, "getting b3",
+ database.MustScan(t, "getting b3",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b3-uuid"),
&b3Record.UUID, &b3Record.Label, &b3Record.USN, &b3Record.Dirty)
- testutils.MustScan(t, "getting b4",
+ database.MustScan(t, "getting b4",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", "b4-uuid"),
&b4Record.UUID, &b4Record.Label, &b4Record.USN, &b4Record.Dirty)
- testutils.AssertEqual(t, b1Record.Label, "bar", "b1 Label mismatch")
- testutils.AssertEqual(t, b1Record.USN, 12, "b1 USN mismatch")
- testutils.AssertEqual(t, b1Record.Dirty, false, "b1 Dirty mismatch")
+ assert.Equal(t, b1Record.Label, "bar", "b1 Label mismatch")
+ assert.Equal(t, b1Record.USN, 12, "b1 USN mismatch")
+ assert.Equal(t, b1Record.Dirty, false, "b1 Dirty mismatch")
- testutils.AssertEqual(t, b2Record.Label, "bar_4", "b2 Label mismatch")
- testutils.AssertEqual(t, b2Record.USN, 2, "b2 USN mismatch")
- testutils.AssertEqual(t, b2Record.Dirty, true, "b2 Dirty mismatch")
+ assert.Equal(t, b2Record.Label, "bar_4", "b2 Label mismatch")
+ assert.Equal(t, b2Record.USN, 2, "b2 USN mismatch")
+ assert.Equal(t, b2Record.Dirty, true, "b2 Dirty mismatch")
- testutils.AssertEqual(t, b3Record.Label, "bar_2", "b3 Label mismatch")
- testutils.AssertEqual(t, b3Record.USN, 3, "b3 USN mismatch")
- testutils.AssertEqual(t, b3Record.Dirty, true, "b3 Dirty mismatch")
+ assert.Equal(t, b3Record.Label, "bar_2", "b3 Label mismatch")
+ assert.Equal(t, b3Record.USN, 3, "b3 USN mismatch")
+ assert.Equal(t, b3Record.Dirty, true, "b3 Dirty mismatch")
- testutils.AssertEqual(t, b4Record.Label, "bar_3", "b4 Label mismatch")
- testutils.AssertEqual(t, b4Record.USN, 4, "b4 USN mismatch")
- testutils.AssertEqual(t, b4Record.Dirty, false, "b4 Dirty mismatch")
+ assert.Equal(t, b4Record.Label, "bar_3", "b4 Label mismatch")
+ assert.Equal(t, b4Record.USN, 4, "b4 USN mismatch")
+ assert.Equal(t, b4Record.Dirty, false, "b4 Dirty mismatch")
})
}
func TestSaveServerState(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
+ ctx := context.InitTestCtx(t, "../../tmp", nil)
+ defer context.TeardownTestCtx(t, ctx)
testutils.Login(t, &ctx)
- defer testutils.TeardownEnv(ctx)
db := ctx.DB
- testutils.MustExec(t, "inserting last synced at", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastSyncAt, int64(1231108742))
- testutils.MustExec(t, "inserting last max usn", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, 8)
+ database.MustExec(t, "inserting last synced at", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastSyncAt, int64(1231108742))
+ database.MustExec(t, "inserting last max usn", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastMaxUSN, 8)
// execute
tx, err := db.Begin()
@@ -1905,13 +1855,13 @@ func TestSaveServerState(t *testing.T) {
var lastSyncedAt int64
var lastMaxUSN int
- testutils.MustScan(t, "getting system value",
- db.QueryRow("SELECT value FROM system WHERE key = ?", infra.SystemLastSyncAt), &lastSyncedAt)
- testutils.MustScan(t, "getting system value",
- db.QueryRow("SELECT value FROM system WHERE key = ?", infra.SystemLastMaxUSN), &lastMaxUSN)
+ database.MustScan(t, "getting system value",
+ db.QueryRow("SELECT value FROM system WHERE key = ?", consts.SystemLastSyncAt), &lastSyncedAt)
+ database.MustScan(t, "getting system value",
+ db.QueryRow("SELECT value FROM system WHERE key = ?", consts.SystemLastMaxUSN), &lastMaxUSN)
- testutils.AssertEqual(t, lastSyncedAt, serverTime, "last synced at mismatch")
- testutils.AssertEqual(t, lastMaxUSN, serverMaxUSN, "last max usn mismatch")
+ assert.Equal(t, lastSyncedAt, serverTime, "last synced at mismatch")
+ assert.Equal(t, lastMaxUSN, serverMaxUSN, "last max usn mismatch")
}
// TestSendBooks tests that books are put to correct 'buckets' by running a test server and recording the
@@ -1919,37 +1869,37 @@ func TestSaveServerState(t *testing.T) {
// are updated accordingly based on the server response.
func TestSendBooks(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
+ ctx := context.InitTestCtx(t, "../../tmp", nil)
+ defer context.TeardownTestCtx(t, ctx)
testutils.Login(t, &ctx)
- defer testutils.TeardownEnv(ctx)
db := ctx.DB
- testutils.MustExec(t, "inserting last max usn", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, 0)
+ database.MustExec(t, "inserting last max usn", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastMaxUSN, 0)
// should be ignored
- testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
- testutils.MustExec(t, "inserting b2", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b2-uuid", "b2-label", 2, false, false)
+ database.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
+ database.MustExec(t, "inserting b2", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b2-uuid", "b2-label", 2, false, false)
// should be created
- testutils.MustExec(t, "inserting b3", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b3-uuid", "b3-label", 0, false, true)
- testutils.MustExec(t, "inserting b4", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b4-uuid", "b4-label", 0, false, true)
+ database.MustExec(t, "inserting b3", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b3-uuid", "b3-label", 0, false, true)
+ database.MustExec(t, "inserting b4", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b4-uuid", "b4-label", 0, false, true)
// should be only expunged locally without syncing to server
- testutils.MustExec(t, "inserting b5", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b5-uuid", "b5-label", 0, true, true)
+ database.MustExec(t, "inserting b5", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b5-uuid", "b5-label", 0, true, true)
// should be deleted
- testutils.MustExec(t, "inserting b6", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b6-uuid", "b6-label", 10, true, true)
+ database.MustExec(t, "inserting b6", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b6-uuid", "b6-label", 10, true, true)
// should be updated
- testutils.MustExec(t, "inserting b7", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b7-uuid", "b7-label", 11, false, true)
- testutils.MustExec(t, "inserting b8", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b8-uuid", "b8-label", 18, false, true)
+ database.MustExec(t, "inserting b7", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b7-uuid", "b7-label", 11, false, true)
+ database.MustExec(t, "inserting b8", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b8-uuid", "b8-label", 18, false, true)
// some random notes
- testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 10, "n1 body", 1541108743, false, false)
- testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", "b5-uuid", 10, "n2 body", 1541108743, false, false)
- testutils.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n3-uuid", "b6-uuid", 10, "n3 body", 1541108743, false, false)
- testutils.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n4-uuid", "b7-uuid", 10, "n4 body", 1541108743, false, false)
+ database.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 10, "n1 body", 1541108743, false, false)
+ database.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", "b5-uuid", 10, "n2 body", 1541108743, false, false)
+ database.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n3-uuid", "b6-uuid", 10, "n3 body", 1541108743, false, false)
+ database.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n4-uuid", "b7-uuid", 10, "n4 body", 1541108743, false, false)
// notes that belong to the created book. Their book_uuid should be updated.
- testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", "b3-uuid", 10, "n5 body", 1541108743, false, false)
- testutils.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", "b3-uuid", 10, "n6 body", 1541108743, false, false)
- testutils.MustExec(t, "inserting n7", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n7-uuid", "b4-uuid", 10, "n7 body", 1541108743, false, false)
+ database.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", "b3-uuid", 10, "n5 body", 1541108743, false, false)
+ database.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", "b3-uuid", 10, "n6 body", 1541108743, false, false)
+ database.MustExec(t, "inserting n7", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n7-uuid", "b4-uuid", 10, "n7 body", 1541108743, false, false)
var createdLabels []string
var updatesUUIDs []string
@@ -2034,51 +1984,51 @@ func TestSendBooks(t *testing.T) {
return strings.Compare(createdLabels[i], createdLabels[j]) < 0
})
- testutils.AssertDeepEqual(t, createdLabels, []string{"b3-label", "b4-label"}, "createdLabels mismatch")
- testutils.AssertDeepEqual(t, updatesUUIDs, []string{"b7-uuid", "b8-uuid"}, "updatesUUIDs mismatch")
- testutils.AssertDeepEqual(t, deletedUUIDs, []string{"b6-uuid"}, "deletedUUIDs mismatch")
+ assert.DeepEqual(t, createdLabels, []string{"b3-label", "b4-label"}, "createdLabels mismatch")
+ assert.DeepEqual(t, updatesUUIDs, []string{"b7-uuid", "b8-uuid"}, "updatesUUIDs mismatch")
+ assert.DeepEqual(t, deletedUUIDs, []string{"b6-uuid"}, "deletedUUIDs mismatch")
- var b1, b2, b3, b4, b7, b8 core.Book
- testutils.MustScan(t, "getting b1", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b1-label"), &b1.UUID, &b1.Dirty)
- testutils.MustScan(t, "getting b2", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b2-label"), &b2.UUID, &b2.Dirty)
- testutils.MustScan(t, "getting b3", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b3-label"), &b3.UUID, &b3.Dirty)
- testutils.MustScan(t, "getting b4", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b4-label"), &b4.UUID, &b4.Dirty)
- testutils.MustScan(t, "getting b7", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b7-label"), &b7.UUID, &b7.Dirty)
- testutils.MustScan(t, "getting b8", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b8-label"), &b8.UUID, &b8.Dirty)
+ var b1, b2, b3, b4, b7, b8 database.Book
+ database.MustScan(t, "getting b1", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b1-label"), &b1.UUID, &b1.Dirty)
+ database.MustScan(t, "getting b2", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b2-label"), &b2.UUID, &b2.Dirty)
+ database.MustScan(t, "getting b3", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b3-label"), &b3.UUID, &b3.Dirty)
+ database.MustScan(t, "getting b4", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b4-label"), &b4.UUID, &b4.Dirty)
+ database.MustScan(t, "getting b7", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b7-label"), &b7.UUID, &b7.Dirty)
+ database.MustScan(t, "getting b8", db.QueryRow("SELECT uuid, dirty FROM books WHERE label = ?", "b8-label"), &b8.UUID, &b8.Dirty)
var bookCount int
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, bookCount, 6, "book count mismatch")
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ assert.Equalf(t, bookCount, 6, "book count mismatch")
- testutils.AssertEqual(t, b1.Dirty, false, "b1 Dirty mismatch")
- testutils.AssertEqual(t, b2.Dirty, false, "b2 Dirty mismatch")
- testutils.AssertEqual(t, b3.Dirty, false, "b3 Dirty mismatch")
- testutils.AssertEqual(t, b4.Dirty, false, "b4 Dirty mismatch")
- testutils.AssertEqual(t, b7.Dirty, false, "b7 Dirty mismatch")
- testutils.AssertEqual(t, b8.Dirty, false, "b8 Dirty mismatch")
- testutils.AssertEqual(t, b1.UUID, "b1-uuid", "b1 UUID mismatch")
- testutils.AssertEqual(t, b2.UUID, "b2-uuid", "b2 UUID mismatch")
+ assert.Equal(t, b1.Dirty, false, "b1 Dirty mismatch")
+ assert.Equal(t, b2.Dirty, false, "b2 Dirty mismatch")
+ assert.Equal(t, b3.Dirty, false, "b3 Dirty mismatch")
+ assert.Equal(t, b4.Dirty, false, "b4 Dirty mismatch")
+ assert.Equal(t, b7.Dirty, false, "b7 Dirty mismatch")
+ assert.Equal(t, b8.Dirty, false, "b8 Dirty mismatch")
+ assert.Equal(t, b1.UUID, "b1-uuid", "b1 UUID mismatch")
+ assert.Equal(t, b2.UUID, "b2-uuid", "b2 UUID mismatch")
// uuids of created books should have been updated
- testutils.AssertEqual(t, b3.UUID, "server-b3-label-uuid", "b3 UUID mismatch")
- testutils.AssertEqual(t, b4.UUID, "server-b4-label-uuid", "b4 UUID mismatch")
- testutils.AssertEqual(t, b7.UUID, "b7-uuid", "b7 UUID mismatch")
- testutils.AssertEqual(t, b8.UUID, "b8-uuid", "b8 UUID mismatch")
+ assert.Equal(t, b3.UUID, "server-b3-label-uuid", "b3 UUID mismatch")
+ assert.Equal(t, b4.UUID, "server-b4-label-uuid", "b4 UUID mismatch")
+ assert.Equal(t, b7.UUID, "b7-uuid", "b7 UUID mismatch")
+ assert.Equal(t, b8.UUID, "b8-uuid", "b8 UUID mismatch")
- var n1, n2, n3, n4, n5, n6, n7 core.Note
- testutils.MustScan(t, "getting n1", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n1 body"), &n1.BookUUID)
- testutils.MustScan(t, "getting n2", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n2 body"), &n2.BookUUID)
- testutils.MustScan(t, "getting n3", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n3 body"), &n3.BookUUID)
- testutils.MustScan(t, "getting n4", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n4 body"), &n4.BookUUID)
- testutils.MustScan(t, "getting n5", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n5 body"), &n5.BookUUID)
- testutils.MustScan(t, "getting n6", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n6 body"), &n6.BookUUID)
- testutils.MustScan(t, "getting n7", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n7 body"), &n7.BookUUID)
- testutils.AssertEqual(t, n1.BookUUID, "b1-uuid", "n1 bookUUID mismatch")
- testutils.AssertEqual(t, n2.BookUUID, "b5-uuid", "n2 bookUUID mismatch")
- testutils.AssertEqual(t, n3.BookUUID, "b6-uuid", "n3 bookUUID mismatch")
- testutils.AssertEqual(t, n4.BookUUID, "b7-uuid", "n4 bookUUID mismatch")
- testutils.AssertEqual(t, n5.BookUUID, "server-b3-label-uuid", "n5 bookUUID mismatch")
- testutils.AssertEqual(t, n6.BookUUID, "server-b3-label-uuid", "n6 bookUUID mismatch")
- testutils.AssertEqual(t, n7.BookUUID, "server-b4-label-uuid", "n7 bookUUID mismatch")
+ var n1, n2, n3, n4, n5, n6, n7 database.Note
+ database.MustScan(t, "getting n1", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n1 body"), &n1.BookUUID)
+ database.MustScan(t, "getting n2", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n2 body"), &n2.BookUUID)
+ database.MustScan(t, "getting n3", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n3 body"), &n3.BookUUID)
+ database.MustScan(t, "getting n4", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n4 body"), &n4.BookUUID)
+ database.MustScan(t, "getting n5", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n5 body"), &n5.BookUUID)
+ database.MustScan(t, "getting n6", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n6 body"), &n6.BookUUID)
+ database.MustScan(t, "getting n7", db.QueryRow("SELECT book_uuid FROM notes WHERE body = ?", "n7 body"), &n7.BookUUID)
+ assert.Equal(t, n1.BookUUID, "b1-uuid", "n1 bookUUID mismatch")
+ assert.Equal(t, n2.BookUUID, "b5-uuid", "n2 bookUUID mismatch")
+ assert.Equal(t, n3.BookUUID, "b6-uuid", "n3 bookUUID mismatch")
+ assert.Equal(t, n4.BookUUID, "b7-uuid", "n4 bookUUID mismatch")
+ assert.Equal(t, n5.BookUUID, "server-b3-label-uuid", "n5 bookUUID mismatch")
+ assert.Equal(t, n6.BookUUID, "server-b3-label-uuid", "n6 bookUUID mismatch")
+ assert.Equal(t, n7.BookUUID, "server-b4-label-uuid", "n7 bookUUID mismatch")
}
func TestSendBooks_isBehind(t *testing.T) {
@@ -2159,15 +2109,15 @@ func TestSendBooks_isBehind(t *testing.T) {
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- testutils.Login(t, &ctx)
+ ctx := context.InitTestCtx(t, "../../tmp", nil)
ctx.APIEndpoint = ts.URL
- defer testutils.TeardownEnv(ctx)
+ defer context.TeardownTestCtx(t, ctx)
+ testutils.Login(t, &ctx)
db := ctx.DB
- testutils.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, tc.systemLastMaxUSN)
- testutils.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 0, false, true)
+ database.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastMaxUSN, tc.systemLastMaxUSN)
+ database.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 0, false, true)
// execute
tx, err := db.Begin()
@@ -2184,7 +2134,7 @@ func TestSendBooks_isBehind(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
+ assert.Equal(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
}()
}
})
@@ -2207,15 +2157,15 @@ func TestSendBooks_isBehind(t *testing.T) {
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- testutils.Login(t, &ctx)
+ ctx := context.InitTestCtx(t, "../../tmp", nil)
ctx.APIEndpoint = ts.URL
- defer testutils.TeardownEnv(ctx)
+ defer context.TeardownTestCtx(t, ctx)
+ testutils.Login(t, &ctx)
db := ctx.DB
- testutils.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, tc.systemLastMaxUSN)
- testutils.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, true, true)
+ database.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastMaxUSN, tc.systemLastMaxUSN)
+ database.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, true, true)
// execute
tx, err := db.Begin()
@@ -2232,7 +2182,7 @@ func TestSendBooks_isBehind(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
+ assert.Equal(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
}()
}
})
@@ -2255,15 +2205,15 @@ func TestSendBooks_isBehind(t *testing.T) {
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- testutils.Login(t, &ctx)
+ ctx := context.InitTestCtx(t, "../../tmp", nil)
ctx.APIEndpoint = ts.URL
- defer testutils.TeardownEnv(ctx)
+ defer context.TeardownTestCtx(t, ctx)
+ testutils.Login(t, &ctx)
db := ctx.DB
- testutils.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, tc.systemLastMaxUSN)
- testutils.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 11, false, true)
+ database.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastMaxUSN, tc.systemLastMaxUSN)
+ database.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 11, false, true)
// execute
tx, err := db.Begin()
@@ -2280,7 +2230,7 @@ func TestSendBooks_isBehind(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
+ assert.Equal(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
}()
}
})
@@ -2290,37 +2240,37 @@ func TestSendBooks_isBehind(t *testing.T) {
// uuid from the incoming data.
func TestSendNotes(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
+ ctx := context.InitTestCtx(t, "../../tmp", nil)
+ defer context.TeardownTestCtx(t, ctx)
testutils.Login(t, &ctx)
- defer testutils.TeardownEnv(ctx)
db := ctx.DB
- testutils.MustExec(t, "inserting last max usn", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, 0)
+ database.MustExec(t, "inserting last max usn", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastMaxUSN, 0)
b1UUID := "b1-uuid"
- testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1UUID, "b1-label", 1, false, false)
+ database.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1UUID, "b1-label", 1, false, false)
// should be ignored
- testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1-body", 1541108743, false, false)
+ database.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1-body", 1541108743, false, false)
// should be created
- testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 0, "n2-body", 1541108743, false, true)
+ database.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 0, "n2-body", 1541108743, false, true)
// should be updated
- testutils.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n3-uuid", b1UUID, 11, "n3-body", 1541108743, false, true)
+ database.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n3-uuid", b1UUID, 11, "n3-body", 1541108743, false, true)
// should be only expunged locally without syncing to server
- testutils.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n4-uuid", b1UUID, 0, "n4-body", 1541108743, true, true)
+ database.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n4-uuid", b1UUID, 0, "n4-body", 1541108743, true, true)
// should be deleted
- testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", b1UUID, 17, "n5-body", 1541108743, true, true)
+ database.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", b1UUID, 17, "n5-body", 1541108743, true, true)
// should be created
- testutils.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", b1UUID, 0, "n6-body", 1541108743, false, true)
+ database.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", b1UUID, 0, "n6-body", 1541108743, false, true)
// should be ignored
- testutils.MustExec(t, "inserting n7", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n7-uuid", b1UUID, 12, "n7-body", 1541108743, false, false)
+ database.MustExec(t, "inserting n7", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n7-uuid", b1UUID, 12, "n7-body", 1541108743, false, false)
// should be updated
- testutils.MustExec(t, "inserting n8", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n8-uuid", b1UUID, 17, "n8-body", 1541108743, false, true)
+ database.MustExec(t, "inserting n8", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n8-uuid", b1UUID, 17, "n8-body", 1541108743, false, true)
// should be deleted
- testutils.MustExec(t, "inserting n9", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n9-uuid", b1UUID, 17, "n9-body", 1541108743, true, true)
+ database.MustExec(t, "inserting n9", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n9-uuid", b1UUID, 17, "n9-body", 1541108743, true, true)
// should be created
- testutils.MustExec(t, "inserting n10", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n10-uuid", b1UUID, 0, "n10-body", 1541108743, false, true)
+ database.MustExec(t, "inserting n10", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n10-uuid", b1UUID, 0, "n10-body", 1541108743, false, true)
var createdBodys []string
var updatedUUIDs []string
@@ -2402,64 +2352,64 @@ func TestSendNotes(t *testing.T) {
return strings.Compare(createdBodys[i], createdBodys[j]) < 0
})
- testutils.AssertDeepEqual(t, createdBodys, []string{"n10-body", "n2-body", "n6-body"}, "createdBodys mismatch")
- testutils.AssertDeepEqual(t, updatedUUIDs, []string{"n3-uuid", "n8-uuid"}, "updatedUUIDs mismatch")
- testutils.AssertDeepEqual(t, deletedUUIDs, []string{"n5-uuid", "n9-uuid"}, "deletedUUIDs mismatch")
+ assert.DeepEqual(t, createdBodys, []string{"n10-body", "n2-body", "n6-body"}, "createdBodys mismatch")
+ assert.DeepEqual(t, updatedUUIDs, []string{"n3-uuid", "n8-uuid"}, "updatedUUIDs mismatch")
+ assert.DeepEqual(t, deletedUUIDs, []string{"n5-uuid", "n9-uuid"}, "deletedUUIDs mismatch")
var noteCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.AssertEqualf(t, noteCount, 7, "note count mismatch")
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ assert.Equalf(t, noteCount, 7, "note count mismatch")
- var n1, n2, n3, n6, n7, n8, n10 core.Note
- testutils.MustScan(t, "getting n1", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n1-body"), &n1.UUID, &n1.AddedOn, &n1.Dirty)
- testutils.MustScan(t, "getting n2", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n2-body"), &n2.UUID, &n2.AddedOn, &n2.Dirty)
- testutils.MustScan(t, "getting n3", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n3-body"), &n3.UUID, &n3.AddedOn, &n3.Dirty)
- testutils.MustScan(t, "getting n6", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n6-body"), &n6.UUID, &n6.AddedOn, &n6.Dirty)
- testutils.MustScan(t, "getting n7", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n7-body"), &n7.UUID, &n7.AddedOn, &n7.Dirty)
- testutils.MustScan(t, "getting n8", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n8-body"), &n8.UUID, &n8.AddedOn, &n8.Dirty)
- testutils.MustScan(t, "getting n10", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n10-body"), &n10.UUID, &n10.AddedOn, &n10.Dirty)
+ var n1, n2, n3, n6, n7, n8, n10 database.Note
+ database.MustScan(t, "getting n1", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n1-body"), &n1.UUID, &n1.AddedOn, &n1.Dirty)
+ database.MustScan(t, "getting n2", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n2-body"), &n2.UUID, &n2.AddedOn, &n2.Dirty)
+ database.MustScan(t, "getting n3", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n3-body"), &n3.UUID, &n3.AddedOn, &n3.Dirty)
+ database.MustScan(t, "getting n6", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n6-body"), &n6.UUID, &n6.AddedOn, &n6.Dirty)
+ database.MustScan(t, "getting n7", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n7-body"), &n7.UUID, &n7.AddedOn, &n7.Dirty)
+ database.MustScan(t, "getting n8", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n8-body"), &n8.UUID, &n8.AddedOn, &n8.Dirty)
+ database.MustScan(t, "getting n10", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n10-body"), &n10.UUID, &n10.AddedOn, &n10.Dirty)
- testutils.AssertEqualf(t, noteCount, 7, "note count mismatch")
+ assert.Equalf(t, noteCount, 7, "note count mismatch")
- testutils.AssertEqual(t, n1.Dirty, false, "n1 Dirty mismatch")
- testutils.AssertEqual(t, n2.Dirty, false, "n2 Dirty mismatch")
- testutils.AssertEqual(t, n3.Dirty, false, "n3 Dirty mismatch")
- testutils.AssertEqual(t, n6.Dirty, false, "n6 Dirty mismatch")
- testutils.AssertEqual(t, n7.Dirty, false, "n7 Dirty mismatch")
- testutils.AssertEqual(t, n8.Dirty, false, "n8 Dirty mismatch")
- testutils.AssertEqual(t, n10.Dirty, false, "n10 Dirty mismatch")
+ assert.Equal(t, n1.Dirty, false, "n1 Dirty mismatch")
+ assert.Equal(t, n2.Dirty, false, "n2 Dirty mismatch")
+ assert.Equal(t, n3.Dirty, false, "n3 Dirty mismatch")
+ assert.Equal(t, n6.Dirty, false, "n6 Dirty mismatch")
+ assert.Equal(t, n7.Dirty, false, "n7 Dirty mismatch")
+ assert.Equal(t, n8.Dirty, false, "n8 Dirty mismatch")
+ assert.Equal(t, n10.Dirty, false, "n10 Dirty mismatch")
- testutils.AssertEqual(t, n1.AddedOn, int64(1541108743), "n1 AddedOn mismatch")
- testutils.AssertEqual(t, n2.AddedOn, int64(1541108743), "n2 AddedOn mismatch")
- testutils.AssertEqual(t, n3.AddedOn, int64(1541108743), "n3 AddedOn mismatch")
- testutils.AssertEqual(t, n6.AddedOn, int64(1541108743), "n6 AddedOn mismatch")
- testutils.AssertEqual(t, n7.AddedOn, int64(1541108743), "n7 AddedOn mismatch")
- testutils.AssertEqual(t, n8.AddedOn, int64(1541108743), "n8 AddedOn mismatch")
- testutils.AssertEqual(t, n10.AddedOn, int64(1541108743), "n10 AddedOn mismatch")
+ assert.Equal(t, n1.AddedOn, int64(1541108743), "n1 AddedOn mismatch")
+ assert.Equal(t, n2.AddedOn, int64(1541108743), "n2 AddedOn mismatch")
+ assert.Equal(t, n3.AddedOn, int64(1541108743), "n3 AddedOn mismatch")
+ assert.Equal(t, n6.AddedOn, int64(1541108743), "n6 AddedOn mismatch")
+ assert.Equal(t, n7.AddedOn, int64(1541108743), "n7 AddedOn mismatch")
+ assert.Equal(t, n8.AddedOn, int64(1541108743), "n8 AddedOn mismatch")
+ assert.Equal(t, n10.AddedOn, int64(1541108743), "n10 AddedOn mismatch")
// UUIDs of created notes should have been updated with those from the server response
- testutils.AssertEqual(t, n1.UUID, "n1-uuid", "n1 UUID mismatch")
- testutils.AssertEqual(t, n2.UUID, "server-n2-body-uuid", "n2 UUID mismatch")
- testutils.AssertEqual(t, n3.UUID, "n3-uuid", "n3 UUID mismatch")
- testutils.AssertEqual(t, n6.UUID, "server-n6-body-uuid", "n6 UUID mismatch")
- testutils.AssertEqual(t, n7.UUID, "n7-uuid", "n7 UUID mismatch")
- testutils.AssertEqual(t, n8.UUID, "n8-uuid", "n8 UUID mismatch")
- testutils.AssertEqual(t, n10.UUID, "server-n10-body-uuid", "n10 UUID mismatch")
+ assert.Equal(t, n1.UUID, "n1-uuid", "n1 UUID mismatch")
+ assert.Equal(t, n2.UUID, "server-n2-body-uuid", "n2 UUID mismatch")
+ assert.Equal(t, n3.UUID, "n3-uuid", "n3 UUID mismatch")
+ assert.Equal(t, n6.UUID, "server-n6-body-uuid", "n6 UUID mismatch")
+ assert.Equal(t, n7.UUID, "n7-uuid", "n7 UUID mismatch")
+ assert.Equal(t, n8.UUID, "n8-uuid", "n8 UUID mismatch")
+ assert.Equal(t, n10.UUID, "server-n10-body-uuid", "n10 UUID mismatch")
}
func TestSendNotes_addedOn(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
+ ctx := context.InitTestCtx(t, "../../tmp", nil)
+ defer context.TeardownTestCtx(t, ctx)
testutils.Login(t, &ctx)
- defer testutils.TeardownEnv(ctx)
db := ctx.DB
- testutils.MustExec(t, "inserting last max usn", db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, 0)
+ database.MustExec(t, "inserting last max usn", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastMaxUSN, 0)
// should be created
b1UUID := "b1-uuid"
- testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 0, "n1-body", 1541108743, false, true)
+ database.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 0, "n1-body", 1541108743, false, true)
// fire up a test server. It decrypts the payload for test purposes.
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -2498,9 +2448,9 @@ func TestSendNotes_addedOn(t *testing.T) {
tx.Commit()
// test
- var n1 core.Note
- testutils.MustScan(t, "getting n1", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n1-body"), &n1.UUID, &n1.AddedOn, &n1.Dirty)
- testutils.AssertEqual(t, n1.AddedOn, int64(1541108743), "n1 AddedOn mismatch")
+ var n1 database.Note
+ database.MustScan(t, "getting n1", db.QueryRow("SELECT uuid, added_on, dirty FROM notes WHERE body = ?", "n1-body"), &n1.UUID, &n1.AddedOn, &n1.Dirty)
+ assert.Equal(t, n1.AddedOn, int64(1541108743), "n1 AddedOn mismatch")
}
func TestSendNotes_isBehind(t *testing.T) {
@@ -2581,16 +2531,16 @@ func TestSendNotes_isBehind(t *testing.T) {
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
+ ctx := context.InitTestCtx(t, "../../tmp", nil)
+ defer context.TeardownTestCtx(t, ctx)
testutils.Login(t, &ctx)
ctx.APIEndpoint = ts.URL
- defer testutils.TeardownEnv(ctx)
db := ctx.DB
- testutils.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, tc.systemLastMaxUSN)
- testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
- testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 1, "n1 body", 1541108743, false, true)
+ database.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastMaxUSN, tc.systemLastMaxUSN)
+ database.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
+ database.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 1, "n1 body", 1541108743, false, true)
// execute
tx, err := db.Begin()
@@ -2607,7 +2557,7 @@ func TestSendNotes_isBehind(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
+ assert.Equal(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
}()
}
})
@@ -2630,16 +2580,16 @@ func TestSendNotes_isBehind(t *testing.T) {
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
+ ctx := context.InitTestCtx(t, "../../tmp", nil)
+ defer context.TeardownTestCtx(t, ctx)
testutils.Login(t, &ctx)
ctx.APIEndpoint = ts.URL
- defer testutils.TeardownEnv(ctx)
db := ctx.DB
- testutils.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, tc.systemLastMaxUSN)
- testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
- testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 2, "n1 body", 1541108743, true, true)
+ database.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastMaxUSN, tc.systemLastMaxUSN)
+ database.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
+ database.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 2, "n1 body", 1541108743, true, true)
// execute
tx, err := db.Begin()
@@ -2656,7 +2606,7 @@ func TestSendNotes_isBehind(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
+ assert.Equal(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
}()
}
})
@@ -2679,16 +2629,16 @@ func TestSendNotes_isBehind(t *testing.T) {
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
+ ctx := context.InitTestCtx(t, "../../tmp", nil)
+ defer context.TeardownTestCtx(t, ctx)
testutils.Login(t, &ctx)
ctx.APIEndpoint = ts.URL
- defer testutils.TeardownEnv(ctx)
db := ctx.DB
- testutils.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", infra.SystemLastMaxUSN, tc.systemLastMaxUSN)
- testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
- testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 8, "n1 body", 1541108743, false, true)
+ database.MustExec(t, fmt.Sprintf("inserting last max usn for test case %d", idx), db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemLastMaxUSN, tc.systemLastMaxUSN)
+ database.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
+ database.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 8, "n1 body", 1541108743, false, true)
// execute
tx, err := db.Begin()
@@ -2705,7 +2655,7 @@ func TestSendNotes_isBehind(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
+ assert.Equal(t, isBehind, tc.expectedIsBehind, fmt.Sprintf("isBehind mismatch for test case %d", idx))
}()
}
})
@@ -2845,16 +2795,14 @@ n1 body edited
for idx, tc := range testCases {
func() {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, "../../tmp/.dnote", nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
-
- testutils.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", b1UUID, "b1-label", 5, false)
- testutils.MustExec(t, fmt.Sprintf("inserting b2 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", b2UUID, "b2-label", 6, false)
- testutils.MustExec(t, fmt.Sprintf("inserting conflitcs book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", conflictBookUUID, "conflicts")
+ database.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", b1UUID, "b1-label", 5, false)
+ database.MustExec(t, fmt.Sprintf("inserting b2 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", b2UUID, "b2-label", 6, false)
+ database.MustExec(t, fmt.Sprintf("inserting conflitcs book for test case %d", idx), db, "INSERT INTO books (uuid, label) VALUES (?, ?)", conflictBookUUID, "conflicts")
n1UUID := utils.GenerateUUID()
- testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, b1UUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientBody, tc.clientDeleted, tc.clientDirty)
+ database.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", n1UUID, b1UUID, tc.clientUSN, tc.addedOn, tc.clientEditedOn, tc.clientBody, tc.clientDeleted, tc.clientDirty)
// execute
tx, err := db.Begin()
@@ -2872,8 +2820,8 @@ n1 body edited
Body: tc.serverBody,
Deleted: tc.serverDeleted,
}
- var localNote core.Note
- testutils.MustScan(t, fmt.Sprintf("getting localNote for test case %d", idx),
+ var localNote database.Note
+ database.MustScan(t, fmt.Sprintf("getting localNote for test case %d", idx),
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", n1UUID),
&localNote.UUID, &localNote.BookUUID, &localNote.USN, &localNote.AddedOn, &localNote.EditedOn, &localNote.Body, &localNote.Deleted, &localNote.Dirty)
@@ -2886,61 +2834,59 @@ n1 body edited
// test
var noteCount, bookCount int
- testutils.MustScan(t, fmt.Sprintf("counting notes for test case %d", idx), db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, fmt.Sprintf("counting books for test case %d", idx), db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, fmt.Sprintf("counting notes for test case %d", idx), db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, fmt.Sprintf("counting books for test case %d", idx), db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, noteCount, 1, fmt.Sprintf("note count mismatch for test case %d", idx))
- testutils.AssertEqualf(t, bookCount, 3, fmt.Sprintf("book count mismatch for test case %d", idx))
+ assert.Equalf(t, noteCount, 1, fmt.Sprintf("note count mismatch for test case %d", idx))
+ assert.Equalf(t, bookCount, 3, fmt.Sprintf("book count mismatch for test case %d", idx))
- var n1Record core.Note
- testutils.MustScan(t, fmt.Sprintf("getting n1Record for test case %d", idx),
+ var n1Record database.Note
+ database.MustScan(t, fmt.Sprintf("getting n1Record for test case %d", idx),
db.QueryRow("SELECT uuid, book_uuid, usn, added_on, edited_on, body, deleted, dirty FROM notes WHERE uuid = ?", n1UUID),
&n1Record.UUID, &n1Record.BookUUID, &n1Record.USN, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.Body, &n1Record.Deleted, &n1Record.Dirty)
- var b1Record core.Book
- testutils.MustScan(t, "getting b1Record for test case",
+ var b1Record database.Book
+ database.MustScan(t, "getting b1Record for test case",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", b1UUID),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Dirty)
- var b2Record core.Book
- testutils.MustScan(t, "getting b2Record for test case",
+ var b2Record database.Book
+ database.MustScan(t, "getting b2Record for test case",
db.QueryRow("SELECT uuid, label, usn, dirty FROM books WHERE uuid = ?", b2UUID),
&b2Record.UUID, &b2Record.Label, &b2Record.USN, &b2Record.Dirty)
- testutils.AssertEqual(t, b1Record.UUID, b1UUID, fmt.Sprintf("b1Record UUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1Record.Label, "b1-label", fmt.Sprintf("b1Record Label mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1Record.USN, 5, fmt.Sprintf("b1Record USN mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1Record.Dirty, false, fmt.Sprintf("b1Record Dirty mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.UUID, b1UUID, fmt.Sprintf("b1Record UUID mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.Label, "b1-label", fmt.Sprintf("b1Record Label mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.USN, 5, fmt.Sprintf("b1Record USN mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.Dirty, false, fmt.Sprintf("b1Record Dirty mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.UUID, b2UUID, fmt.Sprintf("b2Record UUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.Label, "b2-label", fmt.Sprintf("b2Record Label mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.USN, 6, fmt.Sprintf("b2Record USN mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.Dirty, false, fmt.Sprintf("b2Record Dirty mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.UUID, b2UUID, fmt.Sprintf("b2Record UUID mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.Label, "b2-label", fmt.Sprintf("b2Record Label mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.USN, 6, fmt.Sprintf("b2Record USN mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.Dirty, false, fmt.Sprintf("b2Record Dirty mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.UUID, n1UUID, fmt.Sprintf("n1Record UUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.BookUUID, tc.expectedBookUUID, fmt.Sprintf("n1Record BookUUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.USN, tc.expectedUSN, fmt.Sprintf("n1Record USN mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.AddedOn, tc.expectedAddedOn, fmt.Sprintf("n1Record AddedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.EditedOn, tc.expectedEditedOn, fmt.Sprintf("n1Record EditedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.Body, tc.expectedBody, fmt.Sprintf("n1Record Body mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.Deleted, tc.expectedDeleted, fmt.Sprintf("n1Record Deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.Dirty, tc.expectedDirty, fmt.Sprintf("n1Record Dirty mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.UUID, n1UUID, fmt.Sprintf("n1Record UUID mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.BookUUID, tc.expectedBookUUID, fmt.Sprintf("n1Record BookUUID mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.USN, tc.expectedUSN, fmt.Sprintf("n1Record USN mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.AddedOn, tc.expectedAddedOn, fmt.Sprintf("n1Record AddedOn mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.EditedOn, tc.expectedEditedOn, fmt.Sprintf("n1Record EditedOn mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.Body, tc.expectedBody, fmt.Sprintf("n1Record Body mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.Deleted, tc.expectedDeleted, fmt.Sprintf("n1Record Deleted mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.Dirty, tc.expectedDirty, fmt.Sprintf("n1Record Dirty mismatch for test case %d", idx))
}()
}
}
func TestCheckBookPristine(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, "../../tmp/.dnote", nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
-
- testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", "b1-uuid", "b1-label", 5, false)
- testutils.MustExec(t, "inserting b2", db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", "b2-uuid", "b2-label", 6, false)
- testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 1541108743, "n1 body", false)
- testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n2-uuid", "b1-uuid", 1541108743, "n2 body", false)
- testutils.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n3-uuid", "b1-uuid", 1541108743, "n3 body", true)
- testutils.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n4-uuid", "b2-uuid", 1541108743, "n4 body", false)
- testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n5-uuid", "b2-uuid", 1541108743, "n5 body", false)
+ database.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", "b1-uuid", "b1-label", 5, false)
+ database.MustExec(t, "inserting b2", db, "INSERT INTO books (uuid, label, usn, dirty) VALUES (?, ?, ?, ?)", "b2-uuid", "b2-label", 6, false)
+ database.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n1-uuid", "b1-uuid", 1541108743, "n1 body", false)
+ database.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n2-uuid", "b1-uuid", 1541108743, "n2 body", false)
+ database.MustExec(t, "inserting n3", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n3-uuid", "b1-uuid", 1541108743, "n3 body", true)
+ database.MustExec(t, "inserting n4", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n4-uuid", "b2-uuid", 1541108743, "n4 body", false)
+ database.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, added_on, body, dirty) VALUES (?, ?, ?, ?, ?)", "n5-uuid", "b2-uuid", 1541108743, "n5 body", false)
t.Run("b1", func(t *testing.T) {
// execute
@@ -2957,7 +2903,7 @@ func TestCheckBookPristine(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, got, false, "b1 should not be pristine")
+ assert.Equal(t, got, false, "b1 should not be pristine")
})
t.Run("b2", func(t *testing.T) {
@@ -2975,7 +2921,7 @@ func TestCheckBookPristine(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, got, true, "b2 should be pristine")
+ assert.Equal(t, got, true, "b2 should be pristine")
})
}
@@ -3037,7 +2983,7 @@ func TestCheckNoteInList(t *testing.T) {
for idx, tc := range testCases {
got := checkNoteInList(tc.uuid, &list)
- testutils.AssertEqual(t, got, tc.expected, fmt.Sprintf("result mismatch for test case %d", idx))
+ assert.Equal(t, got, tc.expected, fmt.Sprintf("result mismatch for test case %d", idx))
}
}
@@ -3099,16 +3045,14 @@ func TestCheckBookInList(t *testing.T) {
for idx, tc := range testCases {
got := checkBookInList(tc.uuid, &list)
- testutils.AssertEqual(t, got, tc.expected, fmt.Sprintf("result mismatch for test case %d", idx))
+ assert.Equal(t, got, tc.expected, fmt.Sprintf("result mismatch for test case %d", idx))
}
}
func TestCleanLocalNotes(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, "../../tmp/.dnote", nil)
+ defer database.CloseTestDB(t, db)
list := syncList{
Notes: map[string]client.SyncFragNote{
@@ -3140,18 +3084,18 @@ func TestCleanLocalNotes(t *testing.T) {
}
b1UUID := "b1-uuid"
- testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1UUID, "b1-label", 1, false, false)
+ database.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1UUID, "b1-label", 1, false, false)
// exists in the list
- testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, false)
- testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 0, "n2 body", 1541108743, false, true)
+ database.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n1-uuid", b1UUID, 10, "n1 body", 1541108743, false, false)
+ database.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n2-uuid", b1UUID, 0, "n2 body", 1541108743, false, true)
// non-existent in the list but in valid state
// (created in the cli and hasn't been uploaded)
- testutils.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", b1UUID, 0, "n6 body", 1541108743, false, true)
+ database.MustExec(t, "inserting n6", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n6-uuid", b1UUID, 0, "n6 body", 1541108743, false, true)
// non-existent in the list and in an invalid state
- testutils.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", b1UUID, 7, "n5 body", 1541108743, true, true)
- testutils.MustExec(t, "inserting n9", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n9-uuid", b1UUID, 17, "n9 body", 1541108743, true, false)
- testutils.MustExec(t, "inserting n10", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n10-uuid", b1UUID, 0, "n10 body", 1541108743, false, false)
+ database.MustExec(t, "inserting n5", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n5-uuid", b1UUID, 7, "n5 body", 1541108743, true, true)
+ database.MustExec(t, "inserting n9", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n9-uuid", b1UUID, 17, "n9 body", 1541108743, true, false)
+ database.MustExec(t, "inserting n10", db, "INSERT INTO notes (uuid, book_uuid, usn, body, added_on, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", "n10-uuid", b1UUID, 0, "n10 body", 1541108743, false, false)
// execute
tx, err := db.Begin()
@@ -3168,21 +3112,19 @@ func TestCleanLocalNotes(t *testing.T) {
// test
var noteCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.AssertEqual(t, noteCount, 3, "note count mismatch")
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ assert.Equal(t, noteCount, 3, "note count mismatch")
- var n1, n2, n6 core.Note
- testutils.MustScan(t, "getting n1", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", "n1-uuid"), &n1.Dirty)
- testutils.MustScan(t, "getting n2", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", "n2-uuid"), &n2.Dirty)
- testutils.MustScan(t, "getting n6", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", "n6-uuid"), &n6.Dirty)
+ var n1, n2, n6 database.Note
+ database.MustScan(t, "getting n1", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", "n1-uuid"), &n1.Dirty)
+ database.MustScan(t, "getting n2", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", "n2-uuid"), &n2.Dirty)
+ database.MustScan(t, "getting n6", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", "n6-uuid"), &n6.Dirty)
}
func TestCleanLocalBooks(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../../tmp", "../../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, "../../tmp/.dnote", nil)
+ defer database.CloseTestDB(t, db)
list := syncList{
Notes: map[string]client.SyncFragNote{
@@ -3214,14 +3156,14 @@ func TestCleanLocalBooks(t *testing.T) {
}
// existent in the server
- testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
- testutils.MustExec(t, "inserting b3", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b3-uuid", "b3-label", 0, false, true)
+ database.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b1-uuid", "b1-label", 1, false, false)
+ database.MustExec(t, "inserting b3", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b3-uuid", "b3-label", 0, false, true)
// non-existent in the server but in valid state
- testutils.MustExec(t, "inserting b5", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b5-uuid", "b5-label", 0, true, true)
+ database.MustExec(t, "inserting b5", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b5-uuid", "b5-label", 0, true, true)
// non-existent in the server and in an invalid state
- testutils.MustExec(t, "inserting b6", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b6-uuid", "b6-label", 10, true, true)
- testutils.MustExec(t, "inserting b7", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b7-uuid", "b7-label", 11, false, false)
- testutils.MustExec(t, "inserting b8", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b8-uuid", "b8-label", 0, false, false)
+ database.MustExec(t, "inserting b6", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b6-uuid", "b6-label", 10, true, true)
+ database.MustExec(t, "inserting b7", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b7-uuid", "b7-label", 11, false, false)
+ database.MustExec(t, "inserting b8", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", "b8-uuid", "b8-label", 0, false, false)
// execute
tx, err := db.Begin()
@@ -3238,11 +3180,11 @@ func TestCleanLocalBooks(t *testing.T) {
// test
var bookCount int
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqual(t, bookCount, 3, "note count mismatch")
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ assert.Equal(t, bookCount, 3, "note count mismatch")
- var b1, b3, b5 core.Book
- testutils.MustScan(t, "getting b1", db.QueryRow("SELECT label FROM books WHERE uuid = ?", "b1-uuid"), &b1.Label)
- testutils.MustScan(t, "getting b3", db.QueryRow("SELECT label FROM books WHERE uuid = ?", "b3-uuid"), &b3.Label)
- testutils.MustScan(t, "getting b5", db.QueryRow("SELECT label FROM books WHERE uuid = ?", "b5-uuid"), &b5.Label)
+ var b1, b3, b5 database.Book
+ database.MustScan(t, "getting b1", db.QueryRow("SELECT label FROM books WHERE uuid = ?", "b1-uuid"), &b1.Label)
+ database.MustScan(t, "getting b3", db.QueryRow("SELECT label FROM books WHERE uuid = ?", "b3-uuid"), &b3.Label)
+ database.MustScan(t, "getting b5", db.QueryRow("SELECT label FROM books WHERE uuid = ?", "b5-uuid"), &b5.Label)
}
diff --git a/cli/cmd/version/version.go b/pkg/cli/cmd/version/version.go
similarity index 92%
rename from cli/cmd/version/version.go
rename to pkg/cli/cmd/version/version.go
index 27b530e8..456b0602 100644
--- a/cli/cmd/version/version.go
+++ b/pkg/cli/cmd/version/version.go
@@ -21,12 +21,12 @@ package version
import (
"fmt"
- "github.com/dnote/dnote/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/context"
"github.com/spf13/cobra"
)
// NewCmd returns a new version command
-func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
+func NewCmd(ctx context.DnoteCtx) *cobra.Command {
cmd := &cobra.Command{
Use: "version",
Short: "Print the version number of Dnote",
diff --git a/cli/cmd/view/view.go b/pkg/cli/cmd/view/view.go
similarity index 86%
rename from cli/cmd/view/view.go
rename to pkg/cli/cmd/view/view.go
index 6998cb8f..4e255639 100644
--- a/cli/cmd/view/view.go
+++ b/pkg/cli/cmd/view/view.go
@@ -19,14 +19,14 @@
package view
import (
- "github.com/dnote/dnote/cli/core"
- "github.com/dnote/dnote/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/infra"
"github.com/pkg/errors"
"github.com/spf13/cobra"
- "github.com/dnote/dnote/cli/cmd/cat"
- "github.com/dnote/dnote/cli/cmd/ls"
- "github.com/dnote/dnote/cli/utils"
+ "github.com/dnote/dnote/pkg/cli/cmd/cat"
+ "github.com/dnote/dnote/pkg/cli/cmd/ls"
+ "github.com/dnote/dnote/pkg/cli/utils"
)
var example = `
@@ -51,7 +51,7 @@ func preRun(cmd *cobra.Command, args []string) error {
}
// NewCmd returns a new view command
-func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
+func NewCmd(ctx context.DnoteCtx) *cobra.Command {
cmd := &cobra.Command{
Use: "view ",
Aliases: []string{"v"},
@@ -67,9 +67,9 @@ func NewCmd(ctx infra.DnoteCtx) *cobra.Command {
return cmd
}
-func newRun(ctx infra.DnoteCtx) core.RunEFunc {
+func newRun(ctx context.DnoteCtx) infra.RunEFunc {
return func(cmd *cobra.Command, args []string) error {
- var run core.RunEFunc
+ var run infra.RunEFunc
if len(args) == 0 {
run = ls.NewRun(ctx, nameOnly)
diff --git a/pkg/cli/consts/consts.go b/pkg/cli/consts/consts.go
new file mode 100644
index 00000000..87137941
--- /dev/null
+++ b/pkg/cli/consts/consts.go
@@ -0,0 +1,46 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+// Package consts provides definitions of constants
+package consts
+
+var (
+ // DnoteDirName is the name of the directory containing dnote files
+ DnoteDirName = ".dnote"
+ // DnoteDBFileName is a filename for the Dnote SQLite database
+ DnoteDBFileName = "dnote.db"
+ // TmpContentFilename is the filename for a temporary content
+ TmpContentFilename = "DNOTE_TMPCONTENT.md"
+
+ // SystemSchema is the key for schema in the system table
+ SystemSchema = "schema"
+ // SystemRemoteSchema is the key for remote schema in the system table
+ SystemRemoteSchema = "remote_schema"
+ // SystemLastSyncAt is the timestamp of the server at the last sync
+ SystemLastSyncAt = "last_sync_time"
+ // SystemLastMaxUSN is the user's max_usn from the server at the alst sync
+ SystemLastMaxUSN = "last_max_usn"
+ // SystemLastUpgrade is the timestamp at which the system more recently checked for an upgrade
+ SystemLastUpgrade = "last_upgrade"
+ // SystemCipherKey is the encryption key
+ SystemCipherKey = "enc_key"
+ // SystemSessionKey is the session key
+ SystemSessionKey = "session_token"
+ // SystemSessionKeyExpiry is the timestamp at which the session key will expire
+ SystemSessionKeyExpiry = "session_token_expiry"
+)
diff --git a/pkg/cli/context/ctx.go b/pkg/cli/context/ctx.go
new file mode 100644
index 00000000..44112c4c
--- /dev/null
+++ b/pkg/cli/context/ctx.go
@@ -0,0 +1,36 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+// Package context defines dnote context
+package context
+
+import (
+ "github.com/dnote/dnote/pkg/cli/database"
+)
+
+// DnoteCtx is a context holding the information of the current runtime
+type DnoteCtx struct {
+ HomeDir string
+ DnoteDir string
+ APIEndpoint string
+ Version string
+ DB *database.DB
+ SessionKey string
+ SessionKeyExpiry int64
+ CipherKey []byte
+}
diff --git a/pkg/cli/context/operations.go b/pkg/cli/context/operations.go
new file mode 100644
index 00000000..fe1aeb1f
--- /dev/null
+++ b/pkg/cli/context/operations.go
@@ -0,0 +1,48 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+package context
+
+import (
+ "encoding/base64"
+
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/pkg/errors"
+)
+
+// GetCipherKey retrieves the cipher key and decode the base64 into bytes.
+func (ctx DnoteCtx) GetCipherKey() ([]byte, error) {
+ tx, err := ctx.DB.Begin()
+ if err != nil {
+ return nil, errors.Wrap(err, "beginning transaction")
+ }
+
+ var cipherKeyB64 string
+ err = database.GetSystem(tx, consts.SystemCipherKey, &cipherKeyB64)
+ if err != nil {
+ return []byte{}, errors.Wrap(err, "getting enc key")
+ }
+
+ cipherKey, err := base64.StdEncoding.DecodeString(cipherKeyB64)
+ if err != nil {
+ return nil, errors.Wrap(err, "decoding cipherKey from base64")
+ }
+
+ return cipherKey, nil
+}
diff --git a/pkg/cli/context/testutils.go b/pkg/cli/context/testutils.go
new file mode 100644
index 00000000..2e9043fa
--- /dev/null
+++ b/pkg/cli/context/testutils.go
@@ -0,0 +1,41 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+package context
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/database"
+)
+
+// InitTestCtx initializes a test context
+func InitTestCtx(t *testing.T, dnoteDir string, dbOpts *database.TestDBOptions) DnoteCtx {
+ dbPath := fmt.Sprintf("%s/%s", dnoteDir, consts.DnoteDBFileName)
+
+ db := database.InitTestDB(t, dbPath, dbOpts)
+
+ return DnoteCtx{DB: db, DnoteDir: dnoteDir}
+}
+
+// TeardownTestCtx cleans up the test context
+func TeardownTestCtx(t *testing.T, ctx DnoteCtx) {
+ database.CloseTestDB(t, ctx.DB)
+}
diff --git a/cli/crypt/utils.go b/pkg/cli/crypt/crypto.go
similarity index 97%
rename from cli/crypt/utils.go
rename to pkg/cli/crypt/crypto.go
index 61f00800..f949b776 100644
--- a/cli/crypt/utils.go
+++ b/pkg/cli/crypt/crypto.go
@@ -27,7 +27,6 @@ import (
"encoding/base64"
"io"
- "github.com/dnote/dnote/cli/log"
"github.com/pkg/errors"
"golang.org/x/crypto/hkdf"
"golang.org/x/crypto/pbkdf2"
@@ -51,7 +50,6 @@ func runHkdf(secret, salt, info []byte) ([]byte, error) {
// and an authentication key
func MakeKeys(password, email []byte, iteration int) ([]byte, []byte, error) {
masterKey := pbkdf2.Key([]byte(password), []byte(email), iteration, 32, sha256.New)
- log.Debug("email: %s, password: %s", email, password)
authKey, err := runHkdf(masterKey, email, []byte("auth"))
if err != nil {
diff --git a/cli/crypt/utils_test.go b/pkg/cli/crypt/crypto_test.go
similarity index 93%
rename from cli/crypt/utils_test.go
rename to pkg/cli/crypt/crypto_test.go
index 729ddb5c..ee63df2e 100644
--- a/cli/crypt/utils_test.go
+++ b/pkg/cli/crypt/crypto_test.go
@@ -25,7 +25,7 @@ import (
"fmt"
"testing"
- "github.com/dnote/dnote/cli/testutils"
+ "github.com/dnote/dnote/pkg/assert"
"github.com/pkg/errors"
)
@@ -77,7 +77,7 @@ func TestAesGcmEncrypt(t *testing.T) {
t.Fatal(errors.Wrap(err, "decode"))
}
- testutils.AssertDeepEqual(t, plaintext, tc.plaintext, "plaintext mismatch")
+ assert.DeepEqual(t, plaintext, tc.plaintext, "plaintext mismatch")
})
}
}
@@ -112,7 +112,7 @@ func TestAesGcmDecrypt(t *testing.T) {
t.Fatal(errors.Wrap(err, "performing decryption"))
}
- testutils.AssertDeepEqual(t, plaintext, []byte(tc.expectedPlaintext), "plaintext mismatch")
+ assert.DeepEqual(t, plaintext, []byte(tc.expectedPlaintext), "plaintext mismatch")
})
}
}
diff --git a/cli/core/models.go b/pkg/cli/database/models.go
similarity index 90%
rename from cli/core/models.go
rename to pkg/cli/database/models.go
index b41e05d8..0fe26c37 100644
--- a/cli/core/models.go
+++ b/pkg/cli/database/models.go
@@ -16,10 +16,9 @@
* along with Dnote CLI. If not, see .
*/
-package core
+package database
import (
- "github.com/dnote/dnote/cli/infra"
"github.com/pkg/errors"
)
@@ -62,7 +61,7 @@ func NewNote(uuid, bookUUID, body string, addedOn, editedOn int64, usn int, publ
}
// Insert inserts a new note
-func (n Note) Insert(db *infra.DB) error {
+func (n Note) Insert(db *DB) error {
_, err := db.Exec("INSERT INTO notes (uuid, book_uuid, body, added_on, edited_on, usn, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
n.UUID, n.BookUUID, n.Body, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, n.Dirty)
@@ -74,7 +73,7 @@ func (n Note) Insert(db *infra.DB) error {
}
// Update updates the note with the given data
-func (n Note) Update(db *infra.DB) error {
+func (n Note) Update(db *DB) error {
_, err := db.Exec("UPDATE notes SET book_uuid = ?, body = ?, added_on = ?, edited_on = ?, usn = ?, public = ?, deleted = ?, dirty = ? WHERE uuid = ?",
n.BookUUID, n.Body, n.AddedOn, n.EditedOn, n.USN, n.Public, n.Deleted, n.Dirty, n.UUID)
@@ -86,7 +85,7 @@ func (n Note) Update(db *infra.DB) error {
}
// UpdateUUID updates the uuid of a book
-func (n *Note) UpdateUUID(db *infra.DB, newUUID string) error {
+func (n *Note) UpdateUUID(db *DB, newUUID string) error {
_, err := db.Exec("UPDATE notes SET uuid = ? WHERE uuid = ?", newUUID, n.UUID)
if err != nil {
@@ -99,7 +98,7 @@ func (n *Note) UpdateUUID(db *infra.DB, newUUID string) error {
}
// Expunge hard-deletes the note from the database
-func (n Note) Expunge(db *infra.DB) error {
+func (n Note) Expunge(db *DB) error {
_, err := db.Exec("DELETE FROM notes WHERE uuid = ?", n.UUID)
if err != nil {
return errors.Wrap(err, "expunging a note locally")
@@ -120,7 +119,7 @@ func NewBook(uuid, label string, usn int, deleted, dirty bool) Book {
}
// Insert inserts a new book
-func (b Book) Insert(db *infra.DB) error {
+func (b Book) Insert(db *DB) error {
_, err := db.Exec("INSERT INTO books (uuid, label, usn, dirty, deleted) VALUES (?, ?, ?, ?, ?)",
b.UUID, b.Label, b.USN, b.Dirty, b.Deleted)
@@ -132,7 +131,7 @@ func (b Book) Insert(db *infra.DB) error {
}
// Update updates the book with the given data
-func (b Book) Update(db *infra.DB) error {
+func (b Book) Update(db *DB) error {
_, err := db.Exec("UPDATE books SET label = ?, usn = ?, dirty = ?, deleted = ? WHERE uuid = ?",
b.Label, b.USN, b.Dirty, b.Deleted, b.UUID)
@@ -144,7 +143,7 @@ func (b Book) Update(db *infra.DB) error {
}
// UpdateUUID updates the uuid of a book
-func (b *Book) UpdateUUID(db *infra.DB, newUUID string) error {
+func (b *Book) UpdateUUID(db *DB, newUUID string) error {
_, err := db.Exec("UPDATE books SET uuid = ? WHERE uuid = ?", newUUID, b.UUID)
if err != nil {
@@ -157,7 +156,7 @@ func (b *Book) UpdateUUID(db *infra.DB, newUUID string) error {
}
// Expunge hard-deletes the book from the database
-func (b Book) Expunge(db *infra.DB) error {
+func (b Book) Expunge(db *DB) error {
_, err := db.Exec("DELETE FROM books WHERE uuid = ?", b.UUID)
if err != nil {
return errors.Wrap(err, "expunging a book locally")
diff --git a/cli/core/models_test.go b/pkg/cli/database/models_test.go
similarity index 55%
rename from cli/core/models_test.go
rename to pkg/cli/database/models_test.go
index bb3c8369..bdf10e18 100644
--- a/cli/core/models_test.go
+++ b/pkg/cli/database/models_test.go
@@ -16,13 +16,13 @@
* along with Dnote CLI. If not, see .
*/
-package core
+package database
import (
"fmt"
"testing"
- "github.com/dnote/dnote/cli/testutils"
+ "github.com/dnote/dnote/pkg/assert"
"github.com/pkg/errors"
)
@@ -65,15 +65,15 @@ func TestNewNote(t *testing.T) {
for idx, tc := range testCases {
got := NewNote(tc.uuid, tc.bookUUID, tc.body, tc.addedOn, tc.editedOn, tc.usn, tc.public, tc.deleted, tc.dirty)
- testutils.AssertEqual(t, got.UUID, tc.uuid, fmt.Sprintf("UUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.BookUUID, tc.bookUUID, fmt.Sprintf("BookUUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.Body, tc.body, fmt.Sprintf("Body mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.AddedOn, tc.addedOn, fmt.Sprintf("AddedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.EditedOn, tc.editedOn, fmt.Sprintf("EditedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.USN, tc.usn, fmt.Sprintf("USN mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.Public, tc.public, fmt.Sprintf("Public mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.Deleted, tc.deleted, fmt.Sprintf("Deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.Dirty, tc.dirty, fmt.Sprintf("Dirty mismatch for test case %d", idx))
+ assert.Equal(t, got.UUID, tc.uuid, fmt.Sprintf("UUID mismatch for test case %d", idx))
+ assert.Equal(t, got.BookUUID, tc.bookUUID, fmt.Sprintf("BookUUID mismatch for test case %d", idx))
+ assert.Equal(t, got.Body, tc.body, fmt.Sprintf("Body mismatch for test case %d", idx))
+ assert.Equal(t, got.AddedOn, tc.addedOn, fmt.Sprintf("AddedOn mismatch for test case %d", idx))
+ assert.Equal(t, got.EditedOn, tc.editedOn, fmt.Sprintf("EditedOn mismatch for test case %d", idx))
+ assert.Equal(t, got.USN, tc.usn, fmt.Sprintf("USN mismatch for test case %d", idx))
+ assert.Equal(t, got.Public, tc.public, fmt.Sprintf("Public mismatch for test case %d", idx))
+ assert.Equal(t, got.Deleted, tc.deleted, fmt.Sprintf("Deleted mismatch for test case %d", idx))
+ assert.Equal(t, got.Dirty, tc.dirty, fmt.Sprintf("Dirty mismatch for test case %d", idx))
}
}
@@ -116,8 +116,8 @@ func TestNoteInsert(t *testing.T) {
for idx, tc := range testCases {
func() {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
n := Note{
UUID: tc.uuid,
@@ -132,8 +132,6 @@ func TestNoteInsert(t *testing.T) {
}
// execute
- db := ctx.DB
-
tx, err := db.Begin()
if err != nil {
t.Fatalf(errors.Wrap(err, fmt.Sprintf("beginning a transaction for test case %d", idx)).Error())
@@ -151,19 +149,19 @@ func TestNoteInsert(t *testing.T) {
var addedOn, editedOn int64
var usn int
var public, deleted, dirty bool
- testutils.MustScan(t, "getting n1",
+ MustScan(t, "getting n1",
db.QueryRow("SELECT uuid, book_uuid, body, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", tc.uuid),
&uuid, &bookUUID, &body, &addedOn, &editedOn, &usn, &public, &deleted, &dirty)
- testutils.AssertEqual(t, uuid, tc.uuid, fmt.Sprintf("uuid mismatch for test case %d", idx))
- testutils.AssertEqual(t, bookUUID, tc.bookUUID, fmt.Sprintf("bookUUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, body, tc.body, fmt.Sprintf("body mismatch for test case %d", idx))
- testutils.AssertEqual(t, addedOn, tc.addedOn, fmt.Sprintf("addedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, editedOn, tc.editedOn, fmt.Sprintf("editedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, usn, tc.usn, fmt.Sprintf("usn mismatch for test case %d", idx))
- testutils.AssertEqual(t, public, tc.public, fmt.Sprintf("public mismatch for test case %d", idx))
- testutils.AssertEqual(t, deleted, tc.deleted, fmt.Sprintf("deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, dirty, tc.dirty, fmt.Sprintf("dirty mismatch for test case %d", idx))
+ assert.Equal(t, uuid, tc.uuid, fmt.Sprintf("uuid mismatch for test case %d", idx))
+ assert.Equal(t, bookUUID, tc.bookUUID, fmt.Sprintf("bookUUID mismatch for test case %d", idx))
+ assert.Equal(t, body, tc.body, fmt.Sprintf("body mismatch for test case %d", idx))
+ assert.Equal(t, addedOn, tc.addedOn, fmt.Sprintf("addedOn mismatch for test case %d", idx))
+ assert.Equal(t, editedOn, tc.editedOn, fmt.Sprintf("editedOn mismatch for test case %d", idx))
+ assert.Equal(t, usn, tc.usn, fmt.Sprintf("usn mismatch for test case %d", idx))
+ assert.Equal(t, public, tc.public, fmt.Sprintf("public mismatch for test case %d", idx))
+ assert.Equal(t, deleted, tc.deleted, fmt.Sprintf("deleted mismatch for test case %d", idx))
+ assert.Equal(t, dirty, tc.dirty, fmt.Sprintf("dirty mismatch for test case %d", idx))
}()
}
}
@@ -264,8 +262,8 @@ func TestNoteUpdate(t *testing.T) {
for idx, tc := range testCases {
func() {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
n1 := Note{
UUID: tc.uuid,
@@ -290,9 +288,8 @@ func TestNoteUpdate(t *testing.T) {
Dirty: false,
}
- db := ctx.DB
- testutils.MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.USN, n1.AddedOn, n1.EditedOn, n1.Body, n1.Public, n1.Deleted, n1.Dirty)
- testutils.MustExec(t, fmt.Sprintf("inserting n2 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.USN, n2.AddedOn, n2.EditedOn, n2.Body, n2.Public, n2.Deleted, n2.Dirty)
+ MustExec(t, fmt.Sprintf("inserting n1 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.USN, n1.AddedOn, n1.EditedOn, n1.Body, n1.Public, n1.Deleted, n1.Dirty)
+ MustExec(t, fmt.Sprintf("inserting n2 for test case %d", idx), db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.USN, n2.AddedOn, n2.EditedOn, n2.Body, n2.Public, n2.Deleted, n2.Dirty)
// execute
tx, err := db.Begin()
@@ -317,32 +314,32 @@ func TestNoteUpdate(t *testing.T) {
// test
var n1Record, n2Record Note
- testutils.MustScan(t, "getting n1",
+ MustScan(t, "getting n1",
db.QueryRow("SELECT uuid, book_uuid, body, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", tc.uuid),
&n1Record.UUID, &n1Record.BookUUID, &n1Record.Body, &n1Record.AddedOn, &n1Record.EditedOn, &n1Record.USN, &n1Record.Public, &n1Record.Deleted, &n1Record.Dirty)
- testutils.MustScan(t, "getting n2",
+ MustScan(t, "getting n2",
db.QueryRow("SELECT uuid, book_uuid, body, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
&n2Record.UUID, &n2Record.BookUUID, &n2Record.Body, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.USN, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
- testutils.AssertEqual(t, n1Record.UUID, n1.UUID, fmt.Sprintf("n1 uuid mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.BookUUID, tc.newBookUUID, fmt.Sprintf("n1 bookUUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.Body, tc.newBody, fmt.Sprintf("n1 body mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.AddedOn, n1.AddedOn, fmt.Sprintf("n1 addedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.EditedOn, tc.newEditedOn, fmt.Sprintf("n1 editedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.USN, tc.newUSN, fmt.Sprintf("n1 usn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.Public, tc.newPublic, fmt.Sprintf("n1 public mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.Deleted, tc.newDeleted, fmt.Sprintf("n1 deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, n1Record.Dirty, tc.newDirty, fmt.Sprintf("n1 dirty mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.UUID, n1.UUID, fmt.Sprintf("n1 uuid mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.BookUUID, tc.newBookUUID, fmt.Sprintf("n1 bookUUID mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.Body, tc.newBody, fmt.Sprintf("n1 body mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.AddedOn, n1.AddedOn, fmt.Sprintf("n1 addedOn mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.EditedOn, tc.newEditedOn, fmt.Sprintf("n1 editedOn mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.USN, tc.newUSN, fmt.Sprintf("n1 usn mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.Public, tc.newPublic, fmt.Sprintf("n1 public mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.Deleted, tc.newDeleted, fmt.Sprintf("n1 deleted mismatch for test case %d", idx))
+ assert.Equal(t, n1Record.Dirty, tc.newDirty, fmt.Sprintf("n1 dirty mismatch for test case %d", idx))
- testutils.AssertEqual(t, n2Record.UUID, n2.UUID, fmt.Sprintf("n2 uuid mismatch for test case %d", idx))
- testutils.AssertEqual(t, n2Record.BookUUID, n2.BookUUID, fmt.Sprintf("n2 bookUUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, n2Record.Body, n2.Body, fmt.Sprintf("n2 body mismatch for test case %d", idx))
- testutils.AssertEqual(t, n2Record.AddedOn, n2.AddedOn, fmt.Sprintf("n2 addedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n2Record.EditedOn, n2.EditedOn, fmt.Sprintf("n2 editedOn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n2Record.USN, n2.USN, fmt.Sprintf("n2 usn mismatch for test case %d", idx))
- testutils.AssertEqual(t, n2Record.Public, n2.Public, fmt.Sprintf("n2 public mismatch for test case %d", idx))
- testutils.AssertEqual(t, n2Record.Deleted, n2.Deleted, fmt.Sprintf("n2 deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, n2Record.Dirty, n2.Dirty, fmt.Sprintf("n2 dirty mismatch for test case %d", idx))
+ assert.Equal(t, n2Record.UUID, n2.UUID, fmt.Sprintf("n2 uuid mismatch for test case %d", idx))
+ assert.Equal(t, n2Record.BookUUID, n2.BookUUID, fmt.Sprintf("n2 bookUUID mismatch for test case %d", idx))
+ assert.Equal(t, n2Record.Body, n2.Body, fmt.Sprintf("n2 body mismatch for test case %d", idx))
+ assert.Equal(t, n2Record.AddedOn, n2.AddedOn, fmt.Sprintf("n2 addedOn mismatch for test case %d", idx))
+ assert.Equal(t, n2Record.EditedOn, n2.EditedOn, fmt.Sprintf("n2 editedOn mismatch for test case %d", idx))
+ assert.Equal(t, n2Record.USN, n2.USN, fmt.Sprintf("n2 usn mismatch for test case %d", idx))
+ assert.Equal(t, n2Record.Public, n2.Public, fmt.Sprintf("n2 public mismatch for test case %d", idx))
+ assert.Equal(t, n2Record.Deleted, n2.Deleted, fmt.Sprintf("n2 deleted mismatch for test case %d", idx))
+ assert.Equal(t, n2Record.Dirty, n2.Dirty, fmt.Sprintf("n2 dirty mismatch for test case %d", idx))
}()
}
}
@@ -362,8 +359,8 @@ func TestNoteUpdateUUID(t *testing.T) {
for idx, tc := range testCases {
t.Run(fmt.Sprintf("testCase%d", idx), func(t *testing.T) {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
n1 := Note{
UUID: "n1-uuid",
@@ -384,9 +381,8 @@ func TestNoteUpdateUUID(t *testing.T) {
Dirty: false,
}
- db := ctx.DB
- testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.Body, n1.AddedOn, n1.USN, n1.Deleted, n1.Dirty)
- testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.Body, n2.AddedOn, n2.USN, n2.Deleted, n2.Dirty)
+ MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.Body, n1.AddedOn, n1.USN, n1.Deleted, n1.Dirty)
+ MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.Body, n2.AddedOn, n2.USN, n2.Deleted, n2.Dirty)
// execute
tx, err := db.Begin()
@@ -402,24 +398,24 @@ func TestNoteUpdateUUID(t *testing.T) {
// test
var n1Record, n2Record Note
- testutils.MustScan(t, "getting n1",
+ MustScan(t, "getting n1",
db.QueryRow("SELECT uuid, body, usn, deleted, dirty FROM notes WHERE body = ?", "n1-body"),
&n1Record.UUID, &n1Record.Body, &n1Record.USN, &n1Record.Deleted, &n1Record.Dirty)
- testutils.MustScan(t, "getting n2",
+ MustScan(t, "getting n2",
db.QueryRow("SELECT uuid, body, usn, deleted, dirty FROM notes WHERE body = ?", "n2-body"),
&n2Record.UUID, &n2Record.Body, &n2Record.USN, &n2Record.Deleted, &n2Record.Dirty)
- testutils.AssertEqual(t, n1.UUID, tc.newUUID, "n1 original reference uuid mismatch")
- testutils.AssertEqual(t, n1Record.UUID, tc.newUUID, "n1 uuid mismatch")
- testutils.AssertEqual(t, n2Record.UUID, n2.UUID, "n2 uuid mismatch")
+ assert.Equal(t, n1.UUID, tc.newUUID, "n1 original reference uuid mismatch")
+ assert.Equal(t, n1Record.UUID, tc.newUUID, "n1 uuid mismatch")
+ assert.Equal(t, n2Record.UUID, n2.UUID, "n2 uuid mismatch")
})
}
}
func TestNoteExpunge(t *testing.T) {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
n1 := Note{
UUID: "n1-uuid",
@@ -444,9 +440,8 @@ func TestNoteExpunge(t *testing.T) {
Dirty: false,
}
- db := ctx.DB
- testutils.MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.USN, n1.AddedOn, n1.EditedOn, n1.Body, n1.Public, n1.Deleted, n1.Dirty)
- testutils.MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.USN, n2.AddedOn, n2.EditedOn, n2.Body, n2.Public, n2.Deleted, n2.Dirty)
+ MustExec(t, "inserting n1", db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n1.UUID, n1.BookUUID, n1.USN, n1.AddedOn, n1.EditedOn, n1.Body, n1.Public, n1.Deleted, n1.Dirty)
+ MustExec(t, "inserting n2", db, "INSERT INTO notes (uuid, book_uuid, usn, added_on, edited_on, body, public, deleted, dirty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", n2.UUID, n2.BookUUID, n2.USN, n2.AddedOn, n2.EditedOn, n2.Body, n2.Public, n2.Deleted, n2.Dirty)
// execute
tx, err := db.Begin()
@@ -463,24 +458,24 @@ func TestNoteExpunge(t *testing.T) {
// test
var noteCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.AssertEqualf(t, noteCount, 1, "note count mismatch")
+ assert.Equalf(t, noteCount, 1, "note count mismatch")
var n2Record Note
- testutils.MustScan(t, "getting n2",
+ MustScan(t, "getting n2",
db.QueryRow("SELECT uuid, book_uuid, body, added_on, edited_on, usn, public, deleted, dirty FROM notes WHERE uuid = ?", n2.UUID),
&n2Record.UUID, &n2Record.BookUUID, &n2Record.Body, &n2Record.AddedOn, &n2Record.EditedOn, &n2Record.USN, &n2Record.Public, &n2Record.Deleted, &n2Record.Dirty)
- testutils.AssertEqual(t, n2Record.UUID, n2.UUID, "n2 uuid mismatch")
- testutils.AssertEqual(t, n2Record.BookUUID, n2.BookUUID, "n2 bookUUID mismatch")
- testutils.AssertEqual(t, n2Record.Body, n2.Body, "n2 body mismatch")
- testutils.AssertEqual(t, n2Record.AddedOn, n2.AddedOn, "n2 addedOn mismatch")
- testutils.AssertEqual(t, n2Record.EditedOn, n2.EditedOn, "n2 editedOn mismatch")
- testutils.AssertEqual(t, n2Record.USN, n2.USN, "n2 usn mismatch")
- testutils.AssertEqual(t, n2Record.Public, n2.Public, "n2 public mismatch")
- testutils.AssertEqual(t, n2Record.Deleted, n2.Deleted, "n2 deleted mismatch")
- testutils.AssertEqual(t, n2Record.Dirty, n2.Dirty, "n2 dirty mismatch")
+ assert.Equal(t, n2Record.UUID, n2.UUID, "n2 uuid mismatch")
+ assert.Equal(t, n2Record.BookUUID, n2.BookUUID, "n2 bookUUID mismatch")
+ assert.Equal(t, n2Record.Body, n2.Body, "n2 body mismatch")
+ assert.Equal(t, n2Record.AddedOn, n2.AddedOn, "n2 addedOn mismatch")
+ assert.Equal(t, n2Record.EditedOn, n2.EditedOn, "n2 editedOn mismatch")
+ assert.Equal(t, n2Record.USN, n2.USN, "n2 usn mismatch")
+ assert.Equal(t, n2Record.Public, n2.Public, "n2 public mismatch")
+ assert.Equal(t, n2Record.Deleted, n2.Deleted, "n2 deleted mismatch")
+ assert.Equal(t, n2Record.Dirty, n2.Dirty, "n2 dirty mismatch")
}
func TestNewBook(t *testing.T) {
@@ -510,11 +505,11 @@ func TestNewBook(t *testing.T) {
for idx, tc := range testCases {
got := NewBook(tc.uuid, tc.label, tc.usn, tc.deleted, tc.dirty)
- testutils.AssertEqual(t, got.UUID, tc.uuid, fmt.Sprintf("UUID mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.Label, tc.label, fmt.Sprintf("Label mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.USN, tc.usn, fmt.Sprintf("USN mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.Deleted, tc.deleted, fmt.Sprintf("Deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, got.Dirty, tc.dirty, fmt.Sprintf("Dirty mismatch for test case %d", idx))
+ assert.Equal(t, got.UUID, tc.uuid, fmt.Sprintf("UUID mismatch for test case %d", idx))
+ assert.Equal(t, got.Label, tc.label, fmt.Sprintf("Label mismatch for test case %d", idx))
+ assert.Equal(t, got.USN, tc.usn, fmt.Sprintf("USN mismatch for test case %d", idx))
+ assert.Equal(t, got.Deleted, tc.deleted, fmt.Sprintf("Deleted mismatch for test case %d", idx))
+ assert.Equal(t, got.Dirty, tc.dirty, fmt.Sprintf("Dirty mismatch for test case %d", idx))
}
}
@@ -545,8 +540,8 @@ func TestBookInsert(t *testing.T) {
for idx, tc := range testCases {
func() {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
b := Book{
UUID: tc.uuid,
@@ -557,7 +552,6 @@ func TestBookInsert(t *testing.T) {
}
// execute
- db := ctx.DB
tx, err := db.Begin()
if err != nil {
@@ -575,15 +569,15 @@ func TestBookInsert(t *testing.T) {
var uuid, label string
var usn int
var deleted, dirty bool
- testutils.MustScan(t, "getting b1",
+ MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, label, usn, deleted, dirty FROM books WHERE uuid = ?", tc.uuid),
&uuid, &label, &usn, &deleted, &dirty)
- testutils.AssertEqual(t, uuid, tc.uuid, fmt.Sprintf("uuid mismatch for test case %d", idx))
- testutils.AssertEqual(t, label, tc.label, fmt.Sprintf("label mismatch for test case %d", idx))
- testutils.AssertEqual(t, usn, tc.usn, fmt.Sprintf("usn mismatch for test case %d", idx))
- testutils.AssertEqual(t, deleted, tc.deleted, fmt.Sprintf("deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, dirty, tc.dirty, fmt.Sprintf("dirty mismatch for test case %d", idx))
+ assert.Equal(t, uuid, tc.uuid, fmt.Sprintf("uuid mismatch for test case %d", idx))
+ assert.Equal(t, label, tc.label, fmt.Sprintf("label mismatch for test case %d", idx))
+ assert.Equal(t, usn, tc.usn, fmt.Sprintf("usn mismatch for test case %d", idx))
+ assert.Equal(t, deleted, tc.deleted, fmt.Sprintf("deleted mismatch for test case %d", idx))
+ assert.Equal(t, dirty, tc.dirty, fmt.Sprintf("dirty mismatch for test case %d", idx))
}()
}
}
@@ -627,8 +621,8 @@ func TestBookUpdate(t *testing.T) {
for idx, tc := range testCases {
func() {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
b1 := Book{
UUID: "b1-uuid",
@@ -645,9 +639,8 @@ func TestBookUpdate(t *testing.T) {
Dirty: false,
}
- db := ctx.DB
- testutils.MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1.UUID, b1.Label, b1.USN, b1.Deleted, b1.Dirty)
- testutils.MustExec(t, fmt.Sprintf("inserting b2 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b2.UUID, b2.Label, b2.USN, b2.Deleted, b2.Dirty)
+ MustExec(t, fmt.Sprintf("inserting b1 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1.UUID, b1.Label, b1.USN, b1.Deleted, b1.Dirty)
+ MustExec(t, fmt.Sprintf("inserting b2 for test case %d", idx), db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b2.UUID, b2.Label, b2.USN, b2.Deleted, b2.Dirty)
// execute
tx, err := db.Begin()
@@ -669,24 +662,24 @@ func TestBookUpdate(t *testing.T) {
// test
var b1Record, b2Record Book
- testutils.MustScan(t, "getting b1",
+ MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, label, usn, deleted, dirty FROM books WHERE uuid = ?", tc.uuid),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Deleted, &b1Record.Dirty)
- testutils.MustScan(t, "getting b2",
+ MustScan(t, "getting b2",
db.QueryRow("SELECT uuid, label, usn, deleted, dirty FROM books WHERE uuid = ?", b2.UUID),
&b2Record.UUID, &b2Record.Label, &b2Record.USN, &b2Record.Deleted, &b2Record.Dirty)
- testutils.AssertEqual(t, b1Record.UUID, b1.UUID, fmt.Sprintf("b1 uuid mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1Record.Label, tc.newLabel, fmt.Sprintf("b1 label mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1Record.USN, tc.newUSN, fmt.Sprintf("b1 usn mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1Record.Deleted, tc.newDeleted, fmt.Sprintf("b1 deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, b1Record.Dirty, tc.newDirty, fmt.Sprintf("b1 dirty mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.UUID, b1.UUID, fmt.Sprintf("b1 uuid mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.Label, tc.newLabel, fmt.Sprintf("b1 label mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.USN, tc.newUSN, fmt.Sprintf("b1 usn mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.Deleted, tc.newDeleted, fmt.Sprintf("b1 deleted mismatch for test case %d", idx))
+ assert.Equal(t, b1Record.Dirty, tc.newDirty, fmt.Sprintf("b1 dirty mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.UUID, b2.UUID, fmt.Sprintf("b2 uuid mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.Label, b2.Label, fmt.Sprintf("b2 label mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.USN, b2.USN, fmt.Sprintf("b2 usn mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.Deleted, b2.Deleted, fmt.Sprintf("b2 deleted mismatch for test case %d", idx))
- testutils.AssertEqual(t, b2Record.Dirty, b2.Dirty, fmt.Sprintf("b2 dirty mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.UUID, b2.UUID, fmt.Sprintf("b2 uuid mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.Label, b2.Label, fmt.Sprintf("b2 label mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.USN, b2.USN, fmt.Sprintf("b2 usn mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.Deleted, b2.Deleted, fmt.Sprintf("b2 deleted mismatch for test case %d", idx))
+ assert.Equal(t, b2Record.Dirty, b2.Dirty, fmt.Sprintf("b2 dirty mismatch for test case %d", idx))
}()
}
}
@@ -707,8 +700,8 @@ func TestBookUpdateUUID(t *testing.T) {
t.Run(fmt.Sprintf("testCase%d", idx), func(t *testing.T) {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
b1 := Book{
UUID: "b1-uuid",
@@ -725,9 +718,8 @@ func TestBookUpdateUUID(t *testing.T) {
Dirty: false,
}
- db := ctx.DB
- testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1.UUID, b1.Label, b1.USN, b1.Deleted, b1.Dirty)
- testutils.MustExec(t, "inserting b2", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b2.UUID, b2.Label, b2.USN, b2.Deleted, b2.Dirty)
+ MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1.UUID, b1.Label, b1.USN, b1.Deleted, b1.Dirty)
+ MustExec(t, "inserting b2", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b2.UUID, b2.Label, b2.USN, b2.Deleted, b2.Dirty)
// execute
tx, err := db.Begin()
@@ -743,24 +735,24 @@ func TestBookUpdateUUID(t *testing.T) {
// test
var b1Record, b2Record Book
- testutils.MustScan(t, "getting b1",
+ MustScan(t, "getting b1",
db.QueryRow("SELECT uuid, label, usn, deleted, dirty FROM books WHERE label = ?", "b1-label"),
&b1Record.UUID, &b1Record.Label, &b1Record.USN, &b1Record.Deleted, &b1Record.Dirty)
- testutils.MustScan(t, "getting b2",
+ MustScan(t, "getting b2",
db.QueryRow("SELECT uuid, label, usn, deleted, dirty FROM books WHERE label = ?", "b2-label"),
&b2Record.UUID, &b2Record.Label, &b2Record.USN, &b2Record.Deleted, &b2Record.Dirty)
- testutils.AssertEqual(t, b1.UUID, tc.newUUID, "b1 original reference uuid mismatch")
- testutils.AssertEqual(t, b1Record.UUID, tc.newUUID, "b1 uuid mismatch")
- testutils.AssertEqual(t, b2Record.UUID, b2.UUID, "b2 uuid mismatch")
+ assert.Equal(t, b1.UUID, tc.newUUID, "b1 original reference uuid mismatch")
+ assert.Equal(t, b1Record.UUID, tc.newUUID, "b1 uuid mismatch")
+ assert.Equal(t, b2Record.UUID, b2.UUID, "b2 uuid mismatch")
})
}
}
func TestBookExpunge(t *testing.T) {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
b1 := Book{
UUID: "b1-uuid",
@@ -777,9 +769,8 @@ func TestBookExpunge(t *testing.T) {
Dirty: false,
}
- db := ctx.DB
- testutils.MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1.UUID, b1.Label, b1.USN, b1.Deleted, b1.Dirty)
- testutils.MustExec(t, "inserting b2", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b2.UUID, b2.Label, b2.USN, b2.Deleted, b2.Dirty)
+ MustExec(t, "inserting b1", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b1.UUID, b1.Label, b1.USN, b1.Deleted, b1.Dirty)
+ MustExec(t, "inserting b2", db, "INSERT INTO books (uuid, label, usn, deleted, dirty) VALUES (?, ?, ?, ?, ?)", b2.UUID, b2.Label, b2.USN, b2.Deleted, b2.Dirty)
// execute
tx, err := db.Begin()
@@ -796,27 +787,27 @@ func TestBookExpunge(t *testing.T) {
// test
var bookCount int
- testutils.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
- testutils.AssertEqualf(t, bookCount, 1, "book count mismatch")
+ assert.Equalf(t, bookCount, 1, "book count mismatch")
var b2Record Book
- testutils.MustScan(t, "getting b2",
+ MustScan(t, "getting b2",
db.QueryRow("SELECT uuid, label, usn, deleted, dirty FROM books WHERE uuid = ?", "b2-uuid"),
&b2Record.UUID, &b2Record.Label, &b2Record.USN, &b2Record.Deleted, &b2Record.Dirty)
- testutils.AssertEqual(t, b2Record.UUID, b2.UUID, "b2 uuid mismatch")
- testutils.AssertEqual(t, b2Record.Label, b2.Label, "b2 label mismatch")
- testutils.AssertEqual(t, b2Record.USN, b2.USN, "b2 usn mismatch")
- testutils.AssertEqual(t, b2Record.Deleted, b2.Deleted, "b2 deleted mismatch")
- testutils.AssertEqual(t, b2Record.Dirty, b2.Dirty, "b2 dirty mismatch")
+ assert.Equal(t, b2Record.UUID, b2.UUID, "b2 uuid mismatch")
+ assert.Equal(t, b2Record.Label, b2.Label, "b2 label mismatch")
+ assert.Equal(t, b2Record.USN, b2.USN, "b2 usn mismatch")
+ assert.Equal(t, b2Record.Deleted, b2.Deleted, "b2 deleted mismatch")
+ assert.Equal(t, b2Record.Dirty, b2.Dirty, "b2 dirty mismatch")
}
// TestNoteFTS tests that note full text search indices stay in sync with the notes after insert, update and delete
func TestNoteFTS(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
// execute - insert
n := Note{
@@ -830,7 +821,6 @@ func TestNoteFTS(t *testing.T) {
Deleted: false,
Dirty: false,
}
- db := ctx.DB
tx, err := db.Begin()
if err != nil {
@@ -846,13 +836,13 @@ func TestNoteFTS(t *testing.T) {
// test
var noteCount, noteFtsCount, noteSearchCount int
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts"), ¬eFtsCount)
- testutils.MustScan(t, "counting search results", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "foo"), ¬eSearchCount)
+ MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts"), ¬eFtsCount)
+ MustScan(t, "counting search results", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "foo"), ¬eSearchCount)
- testutils.AssertEqual(t, noteCount, 1, "noteCount mismatch")
- testutils.AssertEqual(t, noteFtsCount, 1, "noteFtsCount mismatch")
- testutils.AssertEqual(t, noteSearchCount, 1, "noteSearchCount mismatch")
+ assert.Equal(t, noteCount, 1, "noteCount mismatch")
+ assert.Equal(t, noteFtsCount, 1, "noteFtsCount mismatch")
+ assert.Equal(t, noteSearchCount, 1, "noteSearchCount mismatch")
// execute - update
tx, err = db.Begin()
@@ -869,15 +859,15 @@ func TestNoteFTS(t *testing.T) {
tx.Commit()
// test
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts"), ¬eFtsCount)
- testutils.AssertEqual(t, noteCount, 1, "noteCount mismatch")
- testutils.AssertEqual(t, noteFtsCount, 1, "noteFtsCount mismatch")
+ MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts"), ¬eFtsCount)
+ assert.Equal(t, noteCount, 1, "noteCount mismatch")
+ assert.Equal(t, noteFtsCount, 1, "noteFtsCount mismatch")
- testutils.MustScan(t, "counting search results", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "foo"), ¬eSearchCount)
- testutils.AssertEqual(t, noteSearchCount, 0, "noteSearchCount for foo mismatch")
- testutils.MustScan(t, "counting search results", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "baz"), ¬eSearchCount)
- testutils.AssertEqual(t, noteSearchCount, 1, "noteSearchCount for baz mismatch")
+ MustScan(t, "counting search results", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "foo"), ¬eSearchCount)
+ assert.Equal(t, noteSearchCount, 0, "noteSearchCount for foo mismatch")
+ MustScan(t, "counting search results", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "baz"), ¬eSearchCount)
+ assert.Equal(t, noteSearchCount, 1, "noteSearchCount for baz mismatch")
// execute - delete
tx, err = db.Begin()
@@ -893,9 +883,9 @@ func TestNoteFTS(t *testing.T) {
tx.Commit()
// test
- testutils.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
- testutils.MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts"), ¬eFtsCount)
+ MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts"), ¬eFtsCount)
- testutils.AssertEqual(t, noteCount, 0, "noteCount mismatch")
- testutils.AssertEqual(t, noteFtsCount, 0, "noteFtsCount mismatch")
+ assert.Equal(t, noteCount, 0, "noteCount mismatch")
+ assert.Equal(t, noteFtsCount, 0, "noteFtsCount mismatch")
}
diff --git a/cli/core/operations.go b/pkg/cli/database/queries.go
similarity index 59%
rename from cli/core/operations.go
rename to pkg/cli/database/queries.go
index 73ae8401..661b06eb 100644
--- a/cli/core/operations.go
+++ b/pkg/cli/database/queries.go
@@ -16,17 +16,25 @@
* along with Dnote CLI. If not, see .
*/
-package core
+package database
import (
- "encoding/base64"
+ "database/sql"
- "github.com/dnote/dnote/cli/infra"
"github.com/pkg/errors"
)
+// GetSystem scans the given system configuration record onto the destination
+func GetSystem(db *DB, key string, dest interface{}) error {
+ if err := db.QueryRow("SELECT value FROM system WHERE key = ?", key).Scan(dest); err != nil {
+ return errors.Wrap(err, "finding system configuration record")
+ }
+
+ return nil
+}
+
// InsertSystem inserets a system configuration
-func InsertSystem(db *infra.DB, key, val string) error {
+func InsertSystem(db *DB, key, val string) error {
if _, err := db.Exec("INSERT INTO system (key, value) VALUES (? , ?);", key, val); err != nil {
return errors.Wrap(err, "saving system config")
}
@@ -35,7 +43,7 @@ func InsertSystem(db *infra.DB, key, val string) error {
}
// UpsertSystem inserts or updates a system configuration
-func UpsertSystem(db *infra.DB, key, val string) error {
+func UpsertSystem(db *DB, key, val string) error {
var count int
if err := db.QueryRow("SELECT count(*) FROM system WHERE key = ?", key).Scan(&count); err != nil {
return errors.Wrap(err, "counting system record")
@@ -55,7 +63,7 @@ func UpsertSystem(db *infra.DB, key, val string) error {
}
// UpdateSystem updates a system configuration
-func UpdateSystem(db *infra.DB, key, val interface{}) error {
+func UpdateSystem(db *DB, key, val interface{}) error {
if _, err := db.Exec("UPDATE system SET value = ? WHERE key = ?", val, key); err != nil {
return errors.Wrap(err, "updating system config")
}
@@ -63,17 +71,8 @@ func UpdateSystem(db *infra.DB, key, val interface{}) error {
return nil
}
-// GetSystem scans the given system configuration record onto the destination
-func GetSystem(db *infra.DB, key string, dest interface{}) error {
- if err := db.QueryRow("SELECT value FROM system WHERE key = ?", key).Scan(dest); err != nil {
- return errors.Wrap(err, "finding system configuration record")
- }
-
- return nil
-}
-
// DeleteSystem delets the given system record
-func DeleteSystem(db *infra.DB, key string) error {
+func DeleteSystem(db *DB, key string) error {
if _, err := db.Exec("DELETE FROM system WHERE key = ?", key); err != nil {
return errors.Wrap(err, "deleting system config")
}
@@ -81,23 +80,44 @@ func DeleteSystem(db *infra.DB, key string) error {
return nil
}
-// GetCipherKey retrieves the cipher key and decode the base64 into bytes.
-func GetCipherKey(ctx infra.DnoteCtx) ([]byte, error) {
- db, err := ctx.DB.Begin()
- if err != nil {
- return nil, errors.Wrap(err, "beginning transaction")
- }
-
- var cipherKeyB64 string
- err = GetSystem(db, infra.SystemCipherKey, &cipherKeyB64)
- if err != nil {
- return []byte{}, errors.Wrap(err, "getting enc key")
- }
-
- cipherKey, err := base64.StdEncoding.DecodeString(cipherKeyB64)
- if err != nil {
- return nil, errors.Wrap(err, "decoding cipherKey from base64")
- }
-
- return cipherKey, nil
+// NoteInfo is a basic information about a note
+type NoteInfo struct {
+ RowID int
+ BookLabel string
+ UUID string
+ Content string
+ AddedOn int64
+ EditedOn int64
+}
+
+// GetNoteInfo returns a NoteInfo for the note with the given noteRowID
+func GetNoteInfo(db *DB, noteRowID string) (NoteInfo, error) {
+ var ret NoteInfo
+
+ err := db.QueryRow(`SELECT books.label, notes.uuid, notes.body, notes.added_on, notes.edited_on, notes.rowid
+ FROM notes
+ INNER JOIN books ON books.uuid = notes.book_uuid
+ WHERE notes.rowid = ? AND notes.deleted = false`, noteRowID).
+ Scan(&ret.BookLabel, &ret.UUID, &ret.Content, &ret.AddedOn, &ret.EditedOn, &ret.RowID)
+ if err == sql.ErrNoRows {
+ return ret, errors.Errorf("note %s not found", noteRowID)
+ } else if err != nil {
+ return ret, errors.Wrap(err, "querying the note")
+ }
+
+ return ret, nil
+
+}
+
+// GetBookUUID returns a uuid of a book given a label
+func GetBookUUID(db *DB, label string) (string, error) {
+ var ret string
+ err := db.QueryRow("SELECT uuid FROM books WHERE label = ?", label).Scan(&ret)
+ if err == sql.ErrNoRows {
+ return ret, errors.Errorf("book '%s' not found", label)
+ } else if err != nil {
+ return ret, errors.Wrap(err, "querying the book")
+ }
+
+ return ret, nil
}
diff --git a/cli/core/operations_test.go b/pkg/cli/database/queries_test.go
similarity index 62%
rename from cli/core/operations_test.go
rename to pkg/cli/database/queries_test.go
index 82c742ab..cfcff61f 100644
--- a/cli/core/operations_test.go
+++ b/pkg/cli/database/queries_test.go
@@ -16,13 +16,13 @@
* along with Dnote CLI. If not, see .
*/
-package core
+package database
import (
"fmt"
"testing"
- "github.com/dnote/dnote/cli/testutils"
+ "github.com/dnote/dnote/pkg/assert"
"github.com/pkg/errors"
)
@@ -44,12 +44,10 @@ func TestInsertSystem(t *testing.T) {
for _, tc := range testCases {
t.Run(fmt.Sprintf("insert %s %s", tc.key, tc.val), func(t *testing.T) {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
// execute
- db := ctx.DB
-
tx, err := db.Begin()
if err != nil {
t.Fatalf(errors.Wrap(err, "beginning a transaction").Error())
@@ -64,11 +62,11 @@ func TestInsertSystem(t *testing.T) {
// test
var key, val string
- testutils.MustScan(t, "getting the saved record",
+ MustScan(t, "getting the saved record",
db.QueryRow("SELECT key, value FROM system WHERE key = ?", tc.key), &key, &val)
- testutils.AssertEqual(t, key, tc.key, "key mismatch for test case")
- testutils.AssertEqual(t, val, tc.val, "val mismatch for test case")
+ assert.Equal(t, key, tc.key, "key mismatch for test case")
+ assert.Equal(t, val, tc.val, "val mismatch for test case")
})
}
}
@@ -94,14 +92,13 @@ func TestUpsertSystem(t *testing.T) {
for _, tc := range testCases {
t.Run(fmt.Sprintf("insert %s %s", tc.key, tc.val), func(t *testing.T) {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
- db := ctx.DB
- testutils.MustExec(t, "inserting a system configuration", db, "INSERT INTO system (key, value) VALUES (?, ?)", "baz", "quz")
+ MustExec(t, "inserting a system configuration", db, "INSERT INTO system (key, value) VALUES (?, ?)", "baz", "quz")
var initialSystemCount int
- testutils.MustScan(t, "counting records", db.QueryRow("SELECT count(*) FROM system"), &initialSystemCount)
+ MustScan(t, "counting records", db.QueryRow("SELECT count(*) FROM system"), &initialSystemCount)
// execute
tx, err := db.Begin()
@@ -118,15 +115,15 @@ func TestUpsertSystem(t *testing.T) {
// test
var key, val string
- testutils.MustScan(t, "getting the saved record",
+ MustScan(t, "getting the saved record",
db.QueryRow("SELECT key, value FROM system WHERE key = ?", tc.key), &key, &val)
var systemCount int
- testutils.MustScan(t, "counting records",
+ MustScan(t, "counting records",
db.QueryRow("SELECT count(*) FROM system"), &systemCount)
- testutils.AssertEqual(t, key, tc.key, "key mismatch")
- testutils.AssertEqual(t, val, tc.val, "val mismatch")
- testutils.AssertEqual(t, systemCount, initialSystemCount+tc.countDelta, "count mismatch")
+ assert.Equal(t, key, tc.key, "key mismatch")
+ assert.Equal(t, val, tc.val, "val mismatch")
+ assert.Equal(t, systemCount, initialSystemCount+tc.countDelta, "count mismatch")
})
}
}
@@ -134,12 +131,11 @@ func TestUpsertSystem(t *testing.T) {
func TestGetSystem(t *testing.T) {
t.Run(fmt.Sprintf("get string value"), func(t *testing.T) {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
// execute
- db := ctx.DB
- testutils.MustExec(t, "inserting a system configuration", db, "INSERT INTO system (key, value) VALUES (?, ?)", "foo", "bar")
+ MustExec(t, "inserting a system configuration", db, "INSERT INTO system (key, value) VALUES (?, ?)", "foo", "bar")
tx, err := db.Begin()
if err != nil {
@@ -153,17 +149,16 @@ func TestGetSystem(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, dest, "bar", "dest mismatch")
+ assert.Equal(t, dest, "bar", "dest mismatch")
})
t.Run(fmt.Sprintf("get int64 value"), func(t *testing.T) {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
// execute
- db := ctx.DB
- testutils.MustExec(t, "inserting a system configuration", db, "INSERT INTO system (key, value) VALUES (?, ?)", "foo", 1234)
+ MustExec(t, "inserting a system configuration", db, "INSERT INTO system (key, value) VALUES (?, ?)", "foo", 1234)
tx, err := db.Begin()
if err != nil {
@@ -177,7 +172,7 @@ func TestGetSystem(t *testing.T) {
tx.Commit()
// test
- testutils.AssertEqual(t, dest, int64(1234), "dest mismatch")
+ assert.Equal(t, dest, int64(1234), "dest mismatch")
})
}
@@ -200,15 +195,14 @@ func TestUpdateSystem(t *testing.T) {
for _, tc := range testCases {
t.Run(fmt.Sprintf("update %s %s", tc.key, tc.val), func(t *testing.T) {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer CloseTestDB(t, db)
- db := ctx.DB
- testutils.MustExec(t, "inserting a system configuration", db, "INSERT INTO system (key, value) VALUES (?, ?)", "foo", "fuz")
- testutils.MustExec(t, "inserting a system configuration", db, "INSERT INTO system (key, value) VALUES (?, ?)", "baz", "quz")
+ MustExec(t, "inserting a system configuration", db, "INSERT INTO system (key, value) VALUES (?, ?)", "foo", "fuz")
+ MustExec(t, "inserting a system configuration", db, "INSERT INTO system (key, value) VALUES (?, ?)", "baz", "quz")
var initialSystemCount int
- testutils.MustScan(t, "counting records", db.QueryRow("SELECT count(*) FROM system"), &initialSystemCount)
+ MustScan(t, "counting records", db.QueryRow("SELECT count(*) FROM system"), &initialSystemCount)
// execute
tx, err := db.Begin()
@@ -225,15 +219,15 @@ func TestUpdateSystem(t *testing.T) {
// test
var key, val string
- testutils.MustScan(t, "getting the saved record",
+ MustScan(t, "getting the saved record",
db.QueryRow("SELECT key, value FROM system WHERE key = ?", tc.key), &key, &val)
var systemCount int
- testutils.MustScan(t, "counting records",
+ MustScan(t, "counting records",
db.QueryRow("SELECT count(*) FROM system"), &systemCount)
- testutils.AssertEqual(t, key, tc.key, "key mismatch")
- testutils.AssertEqual(t, val, tc.val, "val mismatch")
- testutils.AssertEqual(t, systemCount, initialSystemCount, "count mismatch")
+ assert.Equal(t, key, tc.key, "key mismatch")
+ assert.Equal(t, val, tc.val, "val mismatch")
+ assert.Equal(t, systemCount, initialSystemCount, "count mismatch")
})
}
}
diff --git a/cli/infra/sql.go b/pkg/cli/database/sql.go
similarity index 90%
rename from cli/infra/sql.go
rename to pkg/cli/database/sql.go
index 17327e27..0de44c2e 100644
--- a/cli/infra/sql.go
+++ b/pkg/cli/database/sql.go
@@ -16,12 +16,14 @@
* along with Dnote CLI. If not, see .
*/
-package infra
+package database
import (
"database/sql"
"github.com/pkg/errors"
+ // use sqlite
+ _ "github.com/mattn/go-sqlite3"
)
// SQLCommon is the minimal interface required by a db connection
@@ -45,27 +47,8 @@ type sqlTx interface {
// DB contains information about the current database connection
type DB struct {
- Conn SQLCommon
-}
-
-// OpenDB initializes a new connection to the sqlite database
-func OpenDB(dbPath string) (*DB, error) {
- dbConn, err := sql.Open("sqlite3", dbPath)
- if err != nil {
- return nil, errors.Wrap(err, "opening db connection")
- }
-
- // Send a ping to ensure that the connection is established
- // if err := dbConn.Ping(); err != nil {
- // dbConn.Close()
- // return nil, errors.Wrap(err, "ping")
- // }
-
- db := &DB{
- Conn: dbConn,
- }
-
- return db, nil
+ Conn SQLCommon
+ Filepath string
}
// Begin begins a transaction
@@ -136,3 +119,18 @@ func (d *DB) Close() error {
return errors.New("can't close db")
}
+
+// Open initializes a new connection to the sqlite database
+func Open(dbPath string) (*DB, error) {
+ dbConn, err := sql.Open("sqlite3", dbPath)
+ if err != nil {
+ return nil, errors.Wrap(err, "opening db connection")
+ }
+
+ db := &DB{
+ Conn: dbConn,
+ Filepath: dbPath,
+ }
+
+ return db, nil
+}
diff --git a/pkg/cli/database/testutils.go b/pkg/cli/database/testutils.go
new file mode 100644
index 00000000..2e36b40e
--- /dev/null
+++ b/pkg/cli/database/testutils.go
@@ -0,0 +1,170 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+package database
+
+import (
+ "database/sql"
+ "fmt"
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/utils"
+ "github.com/pkg/errors"
+)
+
+var defaultSchemaSQL = `CREATE TABLE books
+ (
+ uuid text PRIMARY KEY,
+ label text NOT NULL
+ , dirty bool DEFAULT false, usn int DEFAULT 0 NOT NULL, deleted bool DEFAULT false);
+CREATE TABLE system
+ (
+ key string NOT NULL,
+ value text NOT NULL
+ );
+CREATE UNIQUE INDEX idx_books_label ON books(label);
+CREATE UNIQUE INDEX idx_books_uuid ON books(uuid);
+CREATE TABLE IF NOT EXISTS "notes"
+ (
+ uuid text NOT NULL,
+ book_uuid text NOT NULL,
+ body text NOT NULL,
+ added_on integer NOT NULL,
+ edited_on integer DEFAULT 0,
+ public bool DEFAULT false,
+ dirty bool DEFAULT false,
+ usn int DEFAULT 0 NOT NULL,
+ deleted bool DEFAULT false
+ );
+CREATE VIRTUAL TABLE note_fts USING fts5(content=notes, body, tokenize="porter unicode61 categories 'L* N* Co Ps Pe'")
+/* note_fts(body) */;
+CREATE TABLE IF NOT EXISTS 'note_fts_data'(id INTEGER PRIMARY KEY, block BLOB);
+CREATE TABLE IF NOT EXISTS 'note_fts_idx'(segid, term, pgno, PRIMARY KEY(segid, term)) WITHOUT ROWID;
+CREATE TABLE IF NOT EXISTS 'note_fts_docsize'(id INTEGER PRIMARY KEY, sz BLOB);
+CREATE TABLE IF NOT EXISTS 'note_fts_config'(k PRIMARY KEY, v) WITHOUT ROWID;
+CREATE TRIGGER notes_after_insert AFTER INSERT ON notes BEGIN
+ INSERT INTO note_fts(rowid, body) VALUES (new.rowid, new.body);
+ END;
+CREATE TRIGGER notes_after_delete AFTER DELETE ON notes BEGIN
+ INSERT INTO note_fts(note_fts, rowid, body) VALUES ('delete', old.rowid, old.body);
+ END;
+CREATE TRIGGER notes_after_update AFTER UPDATE ON notes BEGIN
+ INSERT INTO note_fts(note_fts, rowid, body) VALUES ('delete', old.rowid, old.body);
+ INSERT INTO note_fts(rowid, body) VALUES (new.rowid, new.body);
+ END;
+CREATE TABLE actions
+ (
+ uuid text PRIMARY KEY,
+ schema integer NOT NULL,
+ type text NOT NULL,
+ data text NOT NULL,
+ timestamp integer NOT NULL
+ );
+CREATE UNIQUE INDEX idx_notes_uuid ON notes(uuid);
+CREATE INDEX idx_notes_book_uuid ON notes(book_uuid);`
+
+// MustScan scans the given row and fails a test in case of any errors
+func MustScan(t *testing.T, message string, row *sql.Row, args ...interface{}) {
+ err := row.Scan(args...)
+ if err != nil {
+ t.Fatal(errors.Wrap(errors.Wrap(err, "scanning a row"), message))
+ }
+}
+
+// MustExec executes the given SQL query and fails a test if an error occurs
+func MustExec(t *testing.T, message string, db *DB, query string, args ...interface{}) sql.Result {
+ result, err := db.Exec(query, args...)
+ if err != nil {
+ t.Fatal(errors.Wrap(errors.Wrap(err, "executing sql"), message))
+ }
+
+ return result
+}
+
+// TestDBOptions contains options for test database
+type TestDBOptions struct {
+ SchemaSQLPath string
+ SkipMigration bool
+}
+
+// InitTestDB opens a test database connection
+func InitTestDB(t *testing.T, dbPath string, options *TestDBOptions) *DB {
+ db, err := Open(dbPath)
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "opening database connection"))
+ }
+
+ dir, _ := filepath.Split(dbPath)
+ err = os.MkdirAll(dir, 0777)
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "creating the directory for test database file"))
+ }
+
+ var schemaSQL string
+ if options != nil && options.SchemaSQLPath != "" {
+ b := utils.ReadFileAbs(options.SchemaSQLPath)
+ schemaSQL = string(b)
+ } else {
+ schemaSQL = defaultSchemaSQL
+ }
+
+ if _, err := db.Exec(schemaSQL); err != nil {
+ t.Fatal(errors.Wrap(err, "running schema sql"))
+ }
+
+ if options == nil || !options.SkipMigration {
+ MarkMigrationComplete(t, db)
+ }
+
+ return db
+}
+
+// CloseTestDB closes the test database
+func CloseTestDB(t *testing.T, db *DB) {
+ if err := db.Close(); err != nil {
+ t.Fatal(errors.Wrap(err, "closing database"))
+ }
+
+ if err := os.RemoveAll(db.Filepath); err != nil {
+ t.Fatal(errors.Wrap(err, "removing database file"))
+ }
+}
+
+// OpenTestDB opens the database connection to the test database
+func OpenTestDB(t *testing.T, dnoteDir string) *DB {
+ dbPath := fmt.Sprintf("%s/%s", dnoteDir, consts.DnoteDBFileName)
+ db, err := Open(dbPath)
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "opening database connection to the test database"))
+ }
+
+ return db
+}
+
+// MarkMigrationComplete marks all migrations as complete in the database
+func MarkMigrationComplete(t *testing.T, db *DB) {
+ if _, err := db.Exec("INSERT INTO system (key, value) VALUES (? , ?);", consts.SystemSchema, 11); err != nil {
+ t.Fatal(errors.Wrap(err, "inserting schema"))
+ }
+ if _, err := db.Exec("INSERT INTO system (key, value) VALUES (? , ?);", consts.SystemRemoteSchema, 1); err != nil {
+ t.Fatal(errors.Wrap(err, "inserting remote schema"))
+ }
+}
diff --git a/cli/dnote-completion.bash b/pkg/cli/dnote-completion.bash
similarity index 100%
rename from cli/dnote-completion.bash
rename to pkg/cli/dnote-completion.bash
diff --git a/cli/dnote-completion.zsh b/pkg/cli/dnote-completion.zsh
similarity index 100%
rename from cli/dnote-completion.zsh
rename to pkg/cli/dnote-completion.zsh
diff --git a/pkg/cli/infra/config.go b/pkg/cli/infra/config.go
new file mode 100644
index 00000000..83d30d64
--- /dev/null
+++ b/pkg/cli/infra/config.go
@@ -0,0 +1,56 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+package infra
+
+import (
+ "fmt"
+ "io/ioutil"
+
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/pkg/errors"
+ "gopkg.in/yaml.v2"
+)
+
+var (
+ // ConfigFilename is the name of the config file
+ ConfigFilename = "dnoterc"
+)
+
+// GetConfigPath returns the path to the dnote config file
+func GetConfigPath(ctx context.DnoteCtx) string {
+ return fmt.Sprintf("%s/%s", ctx.DnoteDir, ConfigFilename)
+}
+
+// ReadConfig reads the config file
+func ReadConfig(ctx context.DnoteCtx) (Config, error) {
+ var ret Config
+
+ configPath := GetConfigPath(ctx)
+ b, err := ioutil.ReadFile(configPath)
+ if err != nil {
+ return ret, errors.Wrap(err, "reading config file")
+ }
+
+ err = yaml.Unmarshal(b, &ret)
+ if err != nil {
+ return ret, errors.Wrap(err, "unmarshalling config")
+ }
+
+ return ret, nil
+}
diff --git a/pkg/cli/infra/init.go b/pkg/cli/infra/init.go
new file mode 100644
index 00000000..b9eb54b5
--- /dev/null
+++ b/pkg/cli/infra/init.go
@@ -0,0 +1,365 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+// Package infra provides operations and definitions for the
+// local infrastructure for Dnote
+package infra
+
+import (
+ "database/sql"
+ "encoding/base64"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/user"
+ "strconv"
+ "time"
+
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/log"
+ "github.com/dnote/dnote/pkg/cli/migrate"
+ "github.com/dnote/dnote/pkg/cli/utils"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+ "gopkg.in/yaml.v2"
+)
+
+// Config holds dnote configuration
+type Config struct {
+ Editor string
+}
+
+// RunEFunc is a function type of dnote commands
+type RunEFunc func(*cobra.Command, []string) error
+
+func newCtx(apiEndpoint, versionTag string) (context.DnoteCtx, error) {
+ homeDir, err := getHomeDir()
+ if err != nil {
+ return context.DnoteCtx{}, errors.Wrap(err, "Failed to get home dir")
+ }
+ dnoteDir := getDnoteDir(homeDir)
+
+ dnoteDBPath := fmt.Sprintf("%s/%s", dnoteDir, consts.DnoteDBFileName)
+ db, err := database.Open(dnoteDBPath)
+ if err != nil {
+ return context.DnoteCtx{}, errors.Wrap(err, "conntecting to db")
+ }
+
+ ctx := context.DnoteCtx{
+ HomeDir: homeDir,
+ DnoteDir: dnoteDir,
+ APIEndpoint: apiEndpoint,
+ Version: versionTag,
+ DB: db,
+ }
+
+ return ctx, nil
+}
+
+// Init initializes the Dnote environment and returns a new dnote context
+func Init(apiEndpoint, versionTag string) (*context.DnoteCtx, error) {
+ ctx, err := newCtx(apiEndpoint, versionTag)
+ if err != nil {
+ return nil, errors.Wrap(err, "initializing a context")
+ }
+
+ if err := InitFiles(ctx); err != nil {
+ return nil, errors.Wrap(err, "initializing files")
+ }
+
+ if err := InitDB(ctx); err != nil {
+ return nil, errors.Wrap(err, "initializing database")
+ }
+ if err := InitSystem(ctx); err != nil {
+ return nil, errors.Wrap(err, "initializing system data")
+ }
+
+ if err := migrate.Legacy(ctx); err != nil {
+ return nil, errors.Wrap(err, "running legacy migration")
+ }
+ if err := migrate.Run(ctx, migrate.LocalSequence, migrate.LocalMode); err != nil {
+ return nil, errors.Wrap(err, "running migration")
+ }
+
+ ctx, err = SetupCtx(ctx)
+ if err != nil {
+ return nil, errors.Wrap(err, "setting up the context")
+ }
+
+ return &ctx, nil
+}
+
+// SetupCtx populates context and returns a new context
+func SetupCtx(ctx context.DnoteCtx) (context.DnoteCtx, error) {
+ db := ctx.DB
+
+ var sessionKey, cipherKeyB64 string
+ var sessionKeyExpiry int64
+
+ err := db.QueryRow("SELECT value FROM system WHERE key = ?", consts.SystemSessionKey).Scan(&sessionKey)
+ if err != nil && err != sql.ErrNoRows {
+ return ctx, errors.Wrap(err, "finding sesison key")
+ }
+ err = db.QueryRow("SELECT value FROM system WHERE key = ?", consts.SystemCipherKey).Scan(&cipherKeyB64)
+ if err != nil && err != sql.ErrNoRows {
+ return ctx, errors.Wrap(err, "finding sesison key")
+ }
+ err = db.QueryRow("SELECT value FROM system WHERE key = ?", consts.SystemSessionKeyExpiry).Scan(&sessionKeyExpiry)
+ if err != nil && err != sql.ErrNoRows {
+ return ctx, errors.Wrap(err, "finding sesison key expiry")
+ }
+
+ cipherKey, err := base64.StdEncoding.DecodeString(cipherKeyB64)
+ if err != nil {
+ return ctx, errors.Wrap(err, "decoding cipherKey from base64")
+ }
+
+ ret := context.DnoteCtx{
+ HomeDir: ctx.HomeDir,
+ DnoteDir: ctx.DnoteDir,
+ APIEndpoint: ctx.APIEndpoint,
+ Version: ctx.Version,
+ DB: ctx.DB,
+ SessionKey: sessionKey,
+ SessionKeyExpiry: sessionKeyExpiry,
+ CipherKey: cipherKey,
+ }
+
+ return ret, nil
+}
+
+func getDnoteDir(homeDir string) string {
+ var ret string
+
+ dnoteDirEnv := os.Getenv("DNOTE_DIR")
+ if dnoteDirEnv == "" {
+ ret = fmt.Sprintf("%s/%s", homeDir, consts.DnoteDirName)
+ } else {
+ ret = dnoteDirEnv
+ }
+
+ return ret
+}
+
+func getHomeDir() (string, error) {
+ homeDirEnv := os.Getenv("DNOTE_HOME_DIR")
+ if homeDirEnv != "" {
+ return homeDirEnv, nil
+ }
+
+ usr, err := user.Current()
+ if err != nil {
+ return "", errors.Wrap(err, "Failed to get current user")
+ }
+
+ return usr.HomeDir, nil
+}
+
+// InitDB initializes the database.
+// Ideally this process must be a part of migration sequence. But it is performed
+// seaprately because it is a prerequisite for legacy migration.
+func InitDB(ctx context.DnoteCtx) error {
+ log.Debug("initializing the database\n")
+
+ db := ctx.DB
+
+ _, err := db.Exec(`CREATE TABLE IF NOT EXISTS notes
+ (
+ id integer PRIMARY KEY AUTOINCREMENT,
+ uuid text NOT NULL,
+ book_uuid text NOT NULL,
+ content text NOT NULL,
+ added_on integer NOT NULL,
+ edited_on integer DEFAULT 0,
+ public bool DEFAULT false
+ )`)
+ if err != nil {
+ return errors.Wrap(err, "creating notes table")
+ }
+
+ _, err = db.Exec(`CREATE TABLE IF NOT EXISTS books
+ (
+ uuid text PRIMARY KEY,
+ label text NOT NULL
+ )`)
+ if err != nil {
+ return errors.Wrap(err, "creating books table")
+ }
+
+ _, err = db.Exec(`CREATE TABLE IF NOT EXISTS system
+ (
+ key string NOT NULL,
+ value text NOT NULL
+ )`)
+ if err != nil {
+ return errors.Wrap(err, "creating system table")
+ }
+
+ _, err = db.Exec(`CREATE TABLE IF NOT EXISTS actions
+ (
+ uuid text PRIMARY KEY,
+ schema integer NOT NULL,
+ type text NOT NULL,
+ data text NOT NULL,
+ timestamp integer NOT NULL
+ )`)
+ if err != nil {
+ return errors.Wrap(err, "creating actions table")
+ }
+
+ _, err = db.Exec(`
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_books_label ON books(label);
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_notes_uuid ON notes(uuid);
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_books_uuid ON books(uuid);
+ CREATE INDEX IF NOT EXISTS idx_notes_book_uuid ON notes(book_uuid);`)
+ if err != nil {
+ return errors.Wrap(err, "creating indices")
+ }
+
+ return nil
+}
+
+func initSystemKV(db *database.DB, key string, val string) error {
+ var count int
+ if err := db.QueryRow("SELECT count(*) FROM system WHERE key = ?", key).Scan(&count); err != nil {
+ return errors.Wrapf(err, "counting %s", key)
+ }
+
+ if count > 0 {
+ return nil
+ }
+
+ if _, err := db.Exec("INSERT INTO system (key, value) VALUES (?, ?)", key, val); err != nil {
+ db.Rollback()
+ return errors.Wrapf(err, "inserting %s %s", key, val)
+ }
+
+ return nil
+}
+
+// InitSystem inserts system data if missing
+func InitSystem(ctx context.DnoteCtx) error {
+ log.Debug("initializing the system\n")
+
+ db := ctx.DB
+
+ tx, err := db.Begin()
+ if err != nil {
+ return errors.Wrap(err, "beginning a transaction")
+ }
+
+ nowStr := strconv.FormatInt(time.Now().Unix(), 10)
+ if err := initSystemKV(tx, consts.SystemLastUpgrade, nowStr); err != nil {
+ return errors.Wrapf(err, "initializing system config for %s", consts.SystemLastUpgrade)
+ }
+ if err := initSystemKV(tx, consts.SystemLastMaxUSN, "0"); err != nil {
+ return errors.Wrapf(err, "initializing system config for %s", consts.SystemLastMaxUSN)
+ }
+ if err := initSystemKV(tx, consts.SystemLastSyncAt, "0"); err != nil {
+ return errors.Wrapf(err, "initializing system config for %s", consts.SystemLastSyncAt)
+ }
+
+ tx.Commit()
+
+ return nil
+}
+
+// getEditorCommand returns the system's editor command with appropriate flags,
+// if necessary, to make the command wait until editor is close to exit.
+func getEditorCommand() string {
+ editor := os.Getenv("EDITOR")
+
+ var ret string
+
+ switch editor {
+ case "atom":
+ ret = "atom -w"
+ case "subl":
+ ret = "subl -n -w"
+ case "mate":
+ ret = "mate -w"
+ case "vim":
+ ret = "vim"
+ case "nano":
+ ret = "nano"
+ case "emacs":
+ ret = "emacs"
+ case "nvim":
+ ret = "nvim"
+ default:
+ ret = "vi"
+ }
+
+ return ret
+}
+
+// initDnoteDir initializes dnote directory if it does not exist yet
+func initDnoteDir(ctx context.DnoteCtx) error {
+ path := ctx.DnoteDir
+
+ if utils.FileExists(path) {
+ return nil
+ }
+
+ if err := os.MkdirAll(path, 0755); err != nil {
+ return errors.Wrap(err, "Failed to create dnote directory")
+ }
+
+ return nil
+}
+
+// initConfigFile populates a new config file if it does not exist yet
+func initConfigFile(ctx context.DnoteCtx) error {
+ path := GetConfigPath(ctx)
+
+ if utils.FileExists(path) {
+ return nil
+ }
+
+ editor := getEditorCommand()
+
+ config := Config{
+ Editor: editor,
+ }
+
+ b, err := yaml.Marshal(config)
+ if err != nil {
+ return errors.Wrap(err, "marshalling config into YAML")
+ }
+
+ err = ioutil.WriteFile(path, b, 0644)
+ if err != nil {
+ return errors.Wrap(err, "writing the config file")
+ }
+
+ return nil
+}
+
+// InitFiles creates, if necessary, the dnote directory and files inside
+func InitFiles(ctx context.DnoteCtx) error {
+ if err := initDnoteDir(ctx); err != nil {
+ return errors.Wrap(err, "creating the dnote dir")
+ }
+ if err := initConfigFile(ctx); err != nil {
+ return errors.Wrap(err, "generating the config file")
+ }
+
+ return nil
+}
diff --git a/cli/core/core_test.go b/pkg/cli/infra/init_test.go
similarity index 57%
rename from cli/core/core_test.go
rename to pkg/cli/infra/init_test.go
index 2d084e86..f5a15e48 100644
--- a/cli/core/core_test.go
+++ b/pkg/cli/infra/init_test.go
@@ -16,24 +16,23 @@
* along with Dnote CLI. If not, see .
*/
-package core
+package infra
import (
"testing"
- "github.com/dnote/dnote/cli/testutils"
+ "github.com/dnote/dnote/pkg/assert"
+ "github.com/dnote/dnote/pkg/cli/database"
"github.com/pkg/errors"
)
func TestInitSystemKV(t *testing.T) {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
-
- db := ctx.DB
+ db := database.InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer database.CloseTestDB(t, db)
var originalCount int
- testutils.MustScan(t, "counting system configs", db.QueryRow("SELECT count(*) FROM system"), &originalCount)
+ database.MustScan(t, "counting system configs", db.QueryRow("SELECT count(*) FROM system"), &originalCount)
// Execute
tx, err := db.Begin()
@@ -50,25 +49,24 @@ func TestInitSystemKV(t *testing.T) {
// Test
var count int
- testutils.MustScan(t, "counting system configs", db.QueryRow("SELECT count(*) FROM system"), &count)
- testutils.AssertEqual(t, count, originalCount+1, "system count mismatch")
+ database.MustScan(t, "counting system configs", db.QueryRow("SELECT count(*) FROM system"), &count)
+ assert.Equal(t, count, originalCount+1, "system count mismatch")
var val string
- testutils.MustScan(t, "getting system value",
+ database.MustScan(t, "getting system value",
db.QueryRow("SELECT value FROM system WHERE key = ?", "testKey"), &val)
- testutils.AssertEqual(t, val, "testVal", "system value mismatch")
+ assert.Equal(t, val, "testVal", "system value mismatch")
}
func TestInitSystemKV_existing(t *testing.T) {
// Setup
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ db := database.InitTestDB(t, "../tmp/dnote-test.db", nil)
+ defer database.CloseTestDB(t, db)
- db := ctx.DB
- testutils.MustExec(t, "inserting a system config", db, "INSERT INTO system (key, value) VALUES (?, ?)", "testKey", "testVal")
+ database.MustExec(t, "inserting a system config", db, "INSERT INTO system (key, value) VALUES (?, ?)", "testKey", "testVal")
var originalCount int
- testutils.MustScan(t, "counting system configs", db.QueryRow("SELECT count(*) FROM system"), &originalCount)
+ database.MustScan(t, "counting system configs", db.QueryRow("SELECT count(*) FROM system"), &originalCount)
// Execute
tx, err := db.Begin()
@@ -85,11 +83,11 @@ func TestInitSystemKV_existing(t *testing.T) {
// Test
var count int
- testutils.MustScan(t, "counting system configs", db.QueryRow("SELECT count(*) FROM system"), &count)
- testutils.AssertEqual(t, count, originalCount, "system count mismatch")
+ database.MustScan(t, "counting system configs", db.QueryRow("SELECT count(*) FROM system"), &count)
+ assert.Equal(t, count, originalCount, "system count mismatch")
var val string
- testutils.MustScan(t, "getting system value",
+ database.MustScan(t, "getting system value",
db.QueryRow("SELECT value FROM system WHERE key = ?", "testKey"), &val)
- testutils.AssertEqual(t, val, "testVal", "system value should not have been updated")
+ assert.Equal(t, val, "testVal", "system value should not have been updated")
}
diff --git a/cli/install.sh b/pkg/cli/install.sh
similarity index 100%
rename from cli/install.sh
rename to pkg/cli/install.sh
diff --git a/cli/log/log.go b/pkg/cli/log/log.go
similarity index 100%
rename from cli/log/log.go
rename to pkg/cli/log/log.go
diff --git a/pkg/cli/main.go b/pkg/cli/main.go
new file mode 100644
index 00000000..5552ccba
--- /dev/null
+++ b/pkg/cli/main.go
@@ -0,0 +1,71 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+package main
+
+import (
+ "os"
+
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/log"
+ _ "github.com/mattn/go-sqlite3"
+ "github.com/pkg/errors"
+
+ // commands
+ "github.com/dnote/dnote/pkg/cli/cmd/add"
+ "github.com/dnote/dnote/pkg/cli/cmd/cat"
+ "github.com/dnote/dnote/pkg/cli/cmd/edit"
+ "github.com/dnote/dnote/pkg/cli/cmd/find"
+ "github.com/dnote/dnote/pkg/cli/cmd/login"
+ "github.com/dnote/dnote/pkg/cli/cmd/logout"
+ "github.com/dnote/dnote/pkg/cli/cmd/ls"
+ "github.com/dnote/dnote/pkg/cli/cmd/remove"
+ "github.com/dnote/dnote/pkg/cli/cmd/root"
+ "github.com/dnote/dnote/pkg/cli/cmd/sync"
+ "github.com/dnote/dnote/pkg/cli/cmd/version"
+ "github.com/dnote/dnote/pkg/cli/cmd/view"
+)
+
+// apiEndpoint and versionTag are populated during link time
+var apiEndpoint string
+var versionTag = "master"
+
+func main() {
+ ctx, err := infra.Init(apiEndpoint, versionTag)
+ if err != nil {
+ panic(errors.Wrap(err, "initializing context"))
+ }
+ defer ctx.DB.Close()
+
+ root.Register(remove.NewCmd(*ctx))
+ root.Register(edit.NewCmd(*ctx))
+ root.Register(login.NewCmd(*ctx))
+ root.Register(logout.NewCmd(*ctx))
+ root.Register(add.NewCmd(*ctx))
+ root.Register(ls.NewCmd(*ctx))
+ root.Register(sync.NewCmd(*ctx))
+ root.Register(version.NewCmd(*ctx))
+ root.Register(cat.NewCmd(*ctx))
+ root.Register(view.NewCmd(*ctx))
+ root.Register(find.NewCmd(*ctx))
+
+ if err := root.Execute(); err != nil {
+ log.Errorf("%s\n", err.Error())
+ os.Exit(1)
+ }
+}
diff --git a/pkg/cli/main_test.go b/pkg/cli/main_test.go
new file mode 100644
index 00000000..f7102b3a
--- /dev/null
+++ b/pkg/cli/main_test.go
@@ -0,0 +1,333 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+package main
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "testing"
+
+ "github.com/dnote/dnote/pkg/assert"
+ "github.com/dnote/dnote/pkg/cli/consts"
+ // "github.com/dnote/dnote/pkg/cli/core"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/testutils"
+ "github.com/dnote/dnote/pkg/cli/utils"
+ "github.com/pkg/errors"
+)
+
+var binaryName = "test-dnote"
+
+var opts = testutils.RunDnoteCmdOptions{
+ HomeDir: "./tmp",
+ DnoteDir: "./tmp/.dnote",
+}
+
+func TestMain(m *testing.M) {
+ if err := exec.Command("go", "build", "--tags", "fts5", "-o", binaryName).Run(); err != nil {
+ log.Print(errors.Wrap(err, "building a binary").Error())
+ os.Exit(1)
+ }
+
+ os.Exit(m.Run())
+}
+
+func TestInit(t *testing.T) {
+ // Execute
+ testutils.RunDnoteCmd(t, opts, binaryName)
+ defer testutils.RemoveDir(t, opts.HomeDir)
+
+ db := database.OpenTestDB(t, opts.DnoteDir)
+
+ // Test
+ if !utils.FileExists(opts.DnoteDir) {
+ t.Errorf("dnote directory was not initialized")
+ }
+ if !utils.FileExists(fmt.Sprintf("%s/%s", opts.DnoteDir, infra.ConfigFilename)) {
+ t.Errorf("config file was not initialized")
+ }
+
+ var notesTableCount, booksTableCount, systemTableCount int
+ database.MustScan(t, "counting notes",
+ db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type = ? AND name = ?", "table", "notes"), ¬esTableCount)
+ database.MustScan(t, "counting books",
+ db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type = ? AND name = ?", "table", "books"), &booksTableCount)
+ database.MustScan(t, "counting system",
+ db.QueryRow("SELECT count(*) FROM sqlite_master WHERE type = ? AND name = ?", "table", "system"), &systemTableCount)
+
+ assert.Equal(t, notesTableCount, 1, "notes table count mismatch")
+ assert.Equal(t, booksTableCount, 1, "books table count mismatch")
+ assert.Equal(t, systemTableCount, 1, "system table count mismatch")
+
+ // test that all default system configurations are generated
+ var lastUpgrade, lastMaxUSN, lastSyncAt string
+ database.MustScan(t, "scanning last upgrade",
+ db.QueryRow("SELECT value FROM system WHERE key = ?", consts.SystemLastUpgrade), &lastUpgrade)
+ database.MustScan(t, "scanning last max usn",
+ db.QueryRow("SELECT value FROM system WHERE key = ?", consts.SystemLastMaxUSN), &lastMaxUSN)
+ database.MustScan(t, "scanning last sync at",
+ db.QueryRow("SELECT value FROM system WHERE key = ?", consts.SystemLastSyncAt), &lastSyncAt)
+
+ assert.NotEqual(t, lastUpgrade, "", "last upgrade should not be empty")
+ assert.NotEqual(t, lastMaxUSN, "", "last max usn should not be empty")
+ assert.NotEqual(t, lastSyncAt, "", "last sync at should not be empty")
+}
+
+func TestAddNote_NewBook_BodyFlag(t *testing.T) {
+ // Set up
+ testutils.RunDnoteCmd(t, opts, binaryName, "add", "js", "-c", "foo")
+ defer testutils.RemoveDir(t, opts.HomeDir)
+
+ db := database.OpenTestDB(t, opts.DnoteDir)
+
+ // Execute
+
+ // Test
+ var noteCount, bookCount int
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+
+ assert.Equalf(t, bookCount, 1, "book count mismatch")
+ assert.Equalf(t, noteCount, 1, "note count mismatch")
+
+ var book database.Book
+ database.MustScan(t, "getting book", db.QueryRow("SELECT uuid, dirty FROM books where label = ?", "js"), &book.UUID, &book.Dirty)
+ var note database.Note
+ database.MustScan(t, "getting note",
+ db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes where book_uuid = ?", book.UUID), ¬e.UUID, ¬e.Body, ¬e.AddedOn, ¬e.Dirty)
+
+ assert.Equal(t, book.Dirty, true, "Book dirty mismatch")
+
+ assert.NotEqual(t, note.UUID, "", "Note should have UUID")
+ assert.Equal(t, note.Body, "foo", "Note body mismatch")
+ assert.Equal(t, note.Dirty, true, "Note dirty mismatch")
+ assert.NotEqual(t, note.AddedOn, int64(0), "Note added_on mismatch")
+}
+
+func TestAddNote_ExistingBook_BodyFlag(t *testing.T) {
+ // Setup
+ db := database.InitTestDB(t, fmt.Sprintf("%s/%s", opts.DnoteDir, consts.DnoteDBFileName), nil)
+ testutils.Setup3(t, db)
+
+ // Execute
+ testutils.RunDnoteCmd(t, opts, binaryName, "add", "js", "-c", "foo")
+ defer testutils.RemoveDir(t, opts.HomeDir)
+
+ // Test
+
+ var noteCount, bookCount int
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+
+ assert.Equalf(t, bookCount, 1, "book count mismatch")
+ assert.Equalf(t, noteCount, 2, "note count mismatch")
+
+ var n1, n2 database.Note
+ database.MustScan(t, "getting n1",
+ db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"), &n1.UUID, &n1.Body, &n1.AddedOn, &n1.Dirty)
+ database.MustScan(t, "getting n2",
+ db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes WHERE book_uuid = ? AND body = ?", "js-book-uuid", "foo"), &n2.UUID, &n2.Body, &n2.AddedOn, &n2.Dirty)
+
+ var book database.Book
+ database.MustScan(t, "getting book", db.QueryRow("SELECT dirty FROM books where label = ?", "js"), &book.Dirty)
+
+ assert.Equal(t, book.Dirty, false, "Book dirty mismatch")
+
+ assert.NotEqual(t, n1.UUID, "", "n1 should have UUID")
+ assert.Equal(t, n1.Body, "Booleans have toString()", "n1 body mismatch")
+ assert.Equal(t, n1.AddedOn, int64(1515199943), "n1 added_on mismatch")
+ assert.Equal(t, n1.Dirty, false, "n1 dirty mismatch")
+
+ assert.NotEqual(t, n2.UUID, "", "n2 should have UUID")
+ assert.Equal(t, n2.Body, "foo", "n2 body mismatch")
+ assert.Equal(t, n2.Dirty, true, "n2 dirty mismatch")
+}
+
+func TestEditNote_BodyFlag(t *testing.T) {
+ // Setup
+ db := database.InitTestDB(t, fmt.Sprintf("%s/%s", opts.DnoteDir, consts.DnoteDBFileName), nil)
+ testutils.Setup4(t, db)
+
+ // Execute
+ testutils.RunDnoteCmd(t, opts, binaryName, "edit", "2", "-c", "foo bar")
+ defer testutils.RemoveDir(t, opts.HomeDir)
+
+ // Test
+
+ var noteCount, bookCount int
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+
+ assert.Equalf(t, bookCount, 1, "book count mismatch")
+ assert.Equalf(t, noteCount, 2, "note count mismatch")
+
+ var n1, n2 database.Note
+ database.MustScan(t, "getting n1",
+ db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes where book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"), &n1.UUID, &n1.Body, &n1.AddedOn, &n1.Dirty)
+ database.MustScan(t, "getting n2",
+ db.QueryRow("SELECT uuid, body, added_on, dirty FROM notes where book_uuid = ? AND uuid = ?", "js-book-uuid", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f"), &n2.UUID, &n2.Body, &n2.AddedOn, &n2.Dirty)
+
+ assert.Equal(t, n1.UUID, "43827b9a-c2b0-4c06-a290-97991c896653", "n1 should have UUID")
+ assert.Equal(t, n1.Body, "Booleans have toString()", "n1 body mismatch")
+ assert.Equal(t, n1.Dirty, false, "n1 dirty mismatch")
+
+ assert.Equal(t, n2.UUID, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", "Note should have UUID")
+ assert.Equal(t, n2.Body, "foo bar", "Note body mismatch")
+ assert.Equal(t, n2.Dirty, true, "n2 dirty mismatch")
+ assert.NotEqual(t, n2.EditedOn, 0, "Note edited_on mismatch")
+}
+
+func TestRemoveNote(t *testing.T) {
+ // Setup
+ db := database.InitTestDB(t, fmt.Sprintf("%s/%s", opts.DnoteDir, consts.DnoteDBFileName), nil)
+ testutils.Setup2(t, db)
+
+ // Execute
+ testutils.WaitDnoteCmd(t, opts, testutils.UserConfirm, binaryName, "remove", "js", "1")
+ defer testutils.RemoveDir(t, opts.HomeDir)
+
+ // Test
+ var noteCount, bookCount, jsNoteCount, linuxNoteCount int
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting js notes", db.QueryRow("SELECT count(*) FROM notes WHERE book_uuid = ?", "js-book-uuid"), &jsNoteCount)
+ database.MustScan(t, "counting linux notes", db.QueryRow("SELECT count(*) FROM notes WHERE book_uuid = ?", "linux-book-uuid"), &linuxNoteCount)
+
+ assert.Equalf(t, bookCount, 2, "book count mismatch")
+ assert.Equalf(t, noteCount, 3, "note count mismatch")
+ assert.Equal(t, jsNoteCount, 2, "js book should have 2 notes")
+ assert.Equal(t, linuxNoteCount, 1, "linux book book should have 1 note")
+
+ var b1, b2 database.Book
+ var n1, n2, n3 database.Note
+ database.MustScan(t, "getting b1",
+ db.QueryRow("SELECT label, deleted, usn FROM books WHERE uuid = ?", "js-book-uuid"),
+ &b1.Label, &b1.Deleted, &b1.USN)
+ database.MustScan(t, "getting b2",
+ db.QueryRow("SELECT label, deleted, usn FROM books WHERE uuid = ?", "linux-book-uuid"),
+ &b2.Label, &b2.Deleted, &b2.USN)
+ database.MustScan(t, "getting n1",
+ db.QueryRow("SELECT uuid, body, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f"),
+ &n1.UUID, &n1.Body, &n1.AddedOn, &n1.Deleted, &n1.Dirty, &n1.USN)
+ database.MustScan(t, "getting n2",
+ db.QueryRow("SELECT uuid, body, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"),
+ &n2.UUID, &n2.Body, &n2.AddedOn, &n2.Deleted, &n2.Dirty, &n2.USN)
+ database.MustScan(t, "getting n3",
+ db.QueryRow("SELECT uuid, body, added_on, deleted, dirty, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "linux-book-uuid", "3e065d55-6d47-42f2-a6bf-f5844130b2d2"),
+ &n3.UUID, &n3.Body, &n3.AddedOn, &n3.Deleted, &n3.Dirty, &n3.USN)
+
+ assert.Equal(t, b1.Label, "js", "b1 label mismatch")
+ assert.Equal(t, b1.Deleted, false, "b1 deleted mismatch")
+ assert.Equal(t, b1.Dirty, false, "b1 Dirty mismatch")
+ assert.Equal(t, b1.USN, 111, "b1 usn mismatch")
+
+ assert.Equal(t, b2.Label, "linux", "b2 label mismatch")
+ assert.Equal(t, b2.Deleted, false, "b2 deleted mismatch")
+ assert.Equal(t, b2.Dirty, false, "b2 Dirty mismatch")
+ assert.Equal(t, b2.USN, 122, "b2 usn mismatch")
+
+ assert.Equal(t, n1.UUID, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", "n1 should have UUID")
+ assert.Equal(t, n1.Body, "", "n1 body mismatch")
+ assert.Equal(t, n1.Deleted, true, "n1 deleted mismatch")
+ assert.Equal(t, n1.Dirty, true, "n1 Dirty mismatch")
+ assert.Equal(t, n1.USN, 11, "n1 usn mismatch")
+
+ assert.Equal(t, n2.UUID, "43827b9a-c2b0-4c06-a290-97991c896653", "n2 should have UUID")
+ assert.Equal(t, n2.Body, "n2 body", "n2 body mismatch")
+ assert.Equal(t, n2.Deleted, false, "n2 deleted mismatch")
+ assert.Equal(t, n2.Dirty, false, "n2 Dirty mismatch")
+ assert.Equal(t, n2.USN, 12, "n2 usn mismatch")
+
+ assert.Equal(t, n3.UUID, "3e065d55-6d47-42f2-a6bf-f5844130b2d2", "n3 should have UUID")
+ assert.Equal(t, n3.Body, "n3 body", "n3 body mismatch")
+ assert.Equal(t, n3.Deleted, false, "n3 deleted mismatch")
+ assert.Equal(t, n3.Dirty, false, "n3 Dirty mismatch")
+ assert.Equal(t, n3.USN, 13, "n3 usn mismatch")
+}
+
+func TestRemoveBook(t *testing.T) {
+ // Setup
+ db := database.InitTestDB(t, fmt.Sprintf("%s/%s", opts.DnoteDir, consts.DnoteDBFileName), nil)
+ testutils.Setup2(t, db)
+
+ // Execute
+ testutils.WaitDnoteCmd(t, opts, testutils.UserConfirm, binaryName, "remove", "-b", "js")
+ defer testutils.RemoveDir(t, opts.HomeDir)
+
+ // Test
+ var noteCount, bookCount, jsNoteCount, linuxNoteCount int
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ database.MustScan(t, "counting notes", db.QueryRow("SELECT count(*) FROM notes"), ¬eCount)
+ database.MustScan(t, "counting js notes", db.QueryRow("SELECT count(*) FROM notes WHERE book_uuid = ?", "js-book-uuid"), &jsNoteCount)
+ database.MustScan(t, "counting linux notes", db.QueryRow("SELECT count(*) FROM notes WHERE book_uuid = ?", "linux-book-uuid"), &linuxNoteCount)
+
+ assert.Equalf(t, bookCount, 2, "book count mismatch")
+ assert.Equalf(t, noteCount, 3, "note count mismatch")
+ assert.Equal(t, jsNoteCount, 2, "js book should have 2 notes")
+ assert.Equal(t, linuxNoteCount, 1, "linux book book should have 1 note")
+
+ var b1, b2 database.Book
+ var n1, n2, n3 database.Note
+ database.MustScan(t, "getting b1",
+ db.QueryRow("SELECT label, dirty, deleted, usn FROM books WHERE uuid = ?", "js-book-uuid"),
+ &b1.Label, &b1.Dirty, &b1.Deleted, &b1.USN)
+ database.MustScan(t, "getting b2",
+ db.QueryRow("SELECT label, dirty, deleted, usn FROM books WHERE uuid = ?", "linux-book-uuid"),
+ &b2.Label, &b2.Dirty, &b2.Deleted, &b2.USN)
+ database.MustScan(t, "getting n1",
+ db.QueryRow("SELECT uuid, body, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f"),
+ &n1.UUID, &n1.Body, &n1.AddedOn, &n1.Deleted, &n1.Dirty, &n1.USN)
+ database.MustScan(t, "getting n2",
+ db.QueryRow("SELECT uuid, body, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "js-book-uuid", "43827b9a-c2b0-4c06-a290-97991c896653"),
+ &n2.UUID, &n2.Body, &n2.AddedOn, &n2.Deleted, &n2.Dirty, &n2.USN)
+ database.MustScan(t, "getting n3",
+ db.QueryRow("SELECT uuid, body, added_on, dirty, deleted, usn FROM notes WHERE book_uuid = ? AND uuid = ?", "linux-book-uuid", "3e065d55-6d47-42f2-a6bf-f5844130b2d2"),
+ &n3.UUID, &n3.Body, &n3.AddedOn, &n3.Deleted, &n3.Dirty, &n3.USN)
+
+ assert.NotEqual(t, b1.Label, "js", "b1 label mismatch")
+ assert.Equal(t, b1.Dirty, true, "b1 Dirty mismatch")
+ assert.Equal(t, b1.Deleted, true, "b1 deleted mismatch")
+ assert.Equal(t, b1.USN, 111, "b1 usn mismatch")
+
+ assert.Equal(t, b2.Label, "linux", "b2 label mismatch")
+ assert.Equal(t, b2.Dirty, false, "b2 Dirty mismatch")
+ assert.Equal(t, b2.Deleted, false, "b2 deleted mismatch")
+ assert.Equal(t, b2.USN, 122, "b2 usn mismatch")
+
+ assert.Equal(t, n1.UUID, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", "n1 should have UUID")
+ assert.Equal(t, n1.Body, "", "n1 body mismatch")
+ assert.Equal(t, n1.Dirty, true, "n1 Dirty mismatch")
+ assert.Equal(t, n1.Deleted, true, "n1 deleted mismatch")
+ assert.Equal(t, n1.USN, 11, "n1 usn mismatch")
+
+ assert.Equal(t, n2.UUID, "43827b9a-c2b0-4c06-a290-97991c896653", "n2 should have UUID")
+ assert.Equal(t, n2.Body, "", "n2 body mismatch")
+ assert.Equal(t, n2.Dirty, true, "n2 Dirty mismatch")
+ assert.Equal(t, n2.Deleted, true, "n2 deleted mismatch")
+ assert.Equal(t, n2.USN, 12, "n2 usn mismatch")
+
+ assert.Equal(t, n3.UUID, "3e065d55-6d47-42f2-a6bf-f5844130b2d2", "n3 should have UUID")
+ assert.Equal(t, n3.Body, "n3 body", "n3 body mismatch")
+ assert.Equal(t, n3.Dirty, false, "n3 Dirty mismatch")
+ assert.Equal(t, n3.Deleted, false, "n3 deleted mismatch")
+ assert.Equal(t, n3.USN, 13, "n3 usn mismatch")
+}
diff --git a/cli/migrate/fixtures/legacy-2-pre-dnote.json b/pkg/cli/migrate/fixtures/legacy-2-pre-dnote.json
similarity index 100%
rename from cli/migrate/fixtures/legacy-2-pre-dnote.json
rename to pkg/cli/migrate/fixtures/legacy-2-pre-dnote.json
diff --git a/cli/migrate/fixtures/legacy-3-pre-dnote.json b/pkg/cli/migrate/fixtures/legacy-3-pre-dnote.json
similarity index 100%
rename from cli/migrate/fixtures/legacy-3-pre-dnote.json
rename to pkg/cli/migrate/fixtures/legacy-3-pre-dnote.json
diff --git a/cli/migrate/fixtures/legacy-4-pre-dnoterc.yaml b/pkg/cli/migrate/fixtures/legacy-4-pre-dnoterc.yaml
similarity index 100%
rename from cli/migrate/fixtures/legacy-4-pre-dnoterc.yaml
rename to pkg/cli/migrate/fixtures/legacy-4-pre-dnoterc.yaml
diff --git a/cli/migrate/fixtures/legacy-5-post-actions.json b/pkg/cli/migrate/fixtures/legacy-5-post-actions.json
similarity index 100%
rename from cli/migrate/fixtures/legacy-5-post-actions.json
rename to pkg/cli/migrate/fixtures/legacy-5-post-actions.json
diff --git a/cli/migrate/fixtures/legacy-5-pre-actions.json b/pkg/cli/migrate/fixtures/legacy-5-pre-actions.json
similarity index 100%
rename from cli/migrate/fixtures/legacy-5-pre-actions.json
rename to pkg/cli/migrate/fixtures/legacy-5-pre-actions.json
diff --git a/cli/migrate/fixtures/legacy-6-post-dnote.json b/pkg/cli/migrate/fixtures/legacy-6-post-dnote.json
similarity index 100%
rename from cli/migrate/fixtures/legacy-6-post-dnote.json
rename to pkg/cli/migrate/fixtures/legacy-6-post-dnote.json
diff --git a/cli/migrate/fixtures/legacy-6-pre-dnote.json b/pkg/cli/migrate/fixtures/legacy-6-pre-dnote.json
similarity index 100%
rename from cli/migrate/fixtures/legacy-6-pre-dnote.json
rename to pkg/cli/migrate/fixtures/legacy-6-pre-dnote.json
diff --git a/cli/migrate/fixtures/legacy-7-post-actions.json b/pkg/cli/migrate/fixtures/legacy-7-post-actions.json
similarity index 100%
rename from cli/migrate/fixtures/legacy-7-post-actions.json
rename to pkg/cli/migrate/fixtures/legacy-7-post-actions.json
diff --git a/cli/migrate/fixtures/legacy-7-pre-actions.json b/pkg/cli/migrate/fixtures/legacy-7-pre-actions.json
similarity index 100%
rename from cli/migrate/fixtures/legacy-7-pre-actions.json
rename to pkg/cli/migrate/fixtures/legacy-7-pre-actions.json
diff --git a/cli/migrate/fixtures/legacy-8-actions.json b/pkg/cli/migrate/fixtures/legacy-8-actions.json
similarity index 100%
rename from cli/migrate/fixtures/legacy-8-actions.json
rename to pkg/cli/migrate/fixtures/legacy-8-actions.json
diff --git a/cli/migrate/fixtures/legacy-8-dnote.json b/pkg/cli/migrate/fixtures/legacy-8-dnote.json
similarity index 100%
rename from cli/migrate/fixtures/legacy-8-dnote.json
rename to pkg/cli/migrate/fixtures/legacy-8-dnote.json
diff --git a/cli/migrate/fixtures/legacy-8-dnoterc.yaml b/pkg/cli/migrate/fixtures/legacy-8-dnoterc.yaml
similarity index 100%
rename from cli/migrate/fixtures/legacy-8-dnoterc.yaml
rename to pkg/cli/migrate/fixtures/legacy-8-dnoterc.yaml
diff --git a/cli/migrate/fixtures/legacy-8-schema.yaml b/pkg/cli/migrate/fixtures/legacy-8-schema.yaml
similarity index 100%
rename from cli/migrate/fixtures/legacy-8-schema.yaml
rename to pkg/cli/migrate/fixtures/legacy-8-schema.yaml
diff --git a/cli/migrate/fixtures/legacy-8-timestamps.yaml b/pkg/cli/migrate/fixtures/legacy-8-timestamps.yaml
similarity index 100%
rename from cli/migrate/fixtures/legacy-8-timestamps.yaml
rename to pkg/cli/migrate/fixtures/legacy-8-timestamps.yaml
diff --git a/cli/migrate/fixtures/local-1-pre-schema.sql b/pkg/cli/migrate/fixtures/local-1-pre-schema.sql
similarity index 100%
rename from cli/migrate/fixtures/local-1-pre-schema.sql
rename to pkg/cli/migrate/fixtures/local-1-pre-schema.sql
diff --git a/cli/migrate/fixtures/local-10-pre-schema.sql b/pkg/cli/migrate/fixtures/local-10-pre-schema.sql
similarity index 100%
rename from cli/migrate/fixtures/local-10-pre-schema.sql
rename to pkg/cli/migrate/fixtures/local-10-pre-schema.sql
diff --git a/cli/migrate/fixtures/local-11-pre-schema.sql b/pkg/cli/migrate/fixtures/local-11-pre-schema.sql
similarity index 100%
rename from cli/migrate/fixtures/local-11-pre-schema.sql
rename to pkg/cli/migrate/fixtures/local-11-pre-schema.sql
diff --git a/cli/migrate/fixtures/local-5-pre-schema.sql b/pkg/cli/migrate/fixtures/local-5-pre-schema.sql
similarity index 100%
rename from cli/migrate/fixtures/local-5-pre-schema.sql
rename to pkg/cli/migrate/fixtures/local-5-pre-schema.sql
diff --git a/cli/migrate/fixtures/local-7-pre-schema.sql b/pkg/cli/migrate/fixtures/local-7-pre-schema.sql
similarity index 100%
rename from cli/migrate/fixtures/local-7-pre-schema.sql
rename to pkg/cli/migrate/fixtures/local-7-pre-schema.sql
diff --git a/cli/migrate/fixtures/local-8-pre-schema.sql b/pkg/cli/migrate/fixtures/local-8-pre-schema.sql
similarity index 100%
rename from cli/migrate/fixtures/local-8-pre-schema.sql
rename to pkg/cli/migrate/fixtures/local-8-pre-schema.sql
diff --git a/cli/migrate/fixtures/local-9-pre-schema.sql b/pkg/cli/migrate/fixtures/local-9-pre-schema.sql
similarity index 100%
rename from cli/migrate/fixtures/local-9-pre-schema.sql
rename to pkg/cli/migrate/fixtures/local-9-pre-schema.sql
diff --git a/cli/migrate/fixtures/remote-1-pre-schema.sql b/pkg/cli/migrate/fixtures/remote-1-pre-schema.sql
similarity index 100%
rename from cli/migrate/fixtures/remote-1-pre-schema.sql
rename to pkg/cli/migrate/fixtures/remote-1-pre-schema.sql
diff --git a/cli/migrate/legacy.go b/pkg/cli/migrate/legacy.go
similarity index 95%
rename from cli/migrate/legacy.go
rename to pkg/cli/migrate/legacy.go
index ee79a07b..ea537caa 100644
--- a/cli/migrate/legacy.go
+++ b/pkg/cli/migrate/legacy.go
@@ -27,9 +27,9 @@ import (
"os"
"time"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
- "github.com/dnote/dnote/cli/utils"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/log"
+ "github.com/dnote/dnote/pkg/cli/utils"
"github.com/pkg/errors"
"github.com/satori/go.uuid"
"gopkg.in/yaml.v2"
@@ -82,7 +82,7 @@ func makeSchema(complete bool) schema {
}
// Legacy performs migration on JSON-based dnote if necessary
-func Legacy(ctx infra.DnoteCtx) error {
+func Legacy(ctx context.DnoteCtx) error {
// If schema does not exist, no need run a legacy migration
schemaPath := getSchemaPath(ctx)
if ok := utils.FileExists(schemaPath); !ok {
@@ -106,7 +106,7 @@ func Legacy(ctx infra.DnoteCtx) error {
// performMigration backs up current .dnote data, performs migration, and
// restores or cleans backups depending on if there is an error
-func performMigration(ctx infra.DnoteCtx, migrationID int) error {
+func performMigration(ctx context.DnoteCtx, migrationID int) error {
// legacyMigrationV8 is the final migration of the legacy JSON Dnote migration
// migrate to sqlite and return
if migrationID == legacyMigrationV8 {
@@ -162,7 +162,7 @@ func performMigration(ctx infra.DnoteCtx, migrationID int) error {
}
// backupDnoteDir backs up the dnote directory to a temporary backup directory
-func backupDnoteDir(ctx infra.DnoteCtx) error {
+func backupDnoteDir(ctx context.DnoteCtx) error {
srcPath := fmt.Sprintf("%s/.dnote", ctx.HomeDir)
tmpPath := fmt.Sprintf("%s/%s", ctx.HomeDir, backupDirName)
@@ -173,14 +173,14 @@ func backupDnoteDir(ctx infra.DnoteCtx) error {
return nil
}
-func restoreBackup(ctx infra.DnoteCtx) error {
+func restoreBackup(ctx context.DnoteCtx) error {
var err error
defer func() {
if err != nil {
log.Printf(`Failed to restore backup for a failed migration.
Don't worry. Your data is still intact in the backup directory.
- Get help on https://github.com/dnote/dnote/cli/issues`)
+ Get help on https://github.com/dnote/dnote/pkg/cli/issues`)
}
}()
@@ -198,7 +198,7 @@ func restoreBackup(ctx infra.DnoteCtx) error {
return nil
}
-func clearBackup(ctx infra.DnoteCtx) error {
+func clearBackup(ctx context.DnoteCtx) error {
backupPath := fmt.Sprintf("%s/%s", ctx.HomeDir, backupDirName)
if err := os.RemoveAll(backupPath); err != nil {
@@ -209,11 +209,11 @@ func clearBackup(ctx infra.DnoteCtx) error {
}
// getSchemaPath returns the path to the file containing schema info
-func getSchemaPath(ctx infra.DnoteCtx) string {
+func getSchemaPath(ctx context.DnoteCtx) string {
return fmt.Sprintf("%s/%s", ctx.DnoteDir, schemaFilename)
}
-func readSchema(ctx infra.DnoteCtx) (schema, error) {
+func readSchema(ctx context.DnoteCtx) (schema, error) {
var ret schema
path := getSchemaPath(ctx)
@@ -231,7 +231,7 @@ func readSchema(ctx infra.DnoteCtx) (schema, error) {
return ret, nil
}
-func writeSchema(ctx infra.DnoteCtx, s schema) error {
+func writeSchema(ctx context.DnoteCtx, s schema) error {
path := getSchemaPath(ctx)
d, err := yaml.Marshal(&s)
if err != nil {
@@ -245,7 +245,7 @@ func writeSchema(ctx infra.DnoteCtx, s schema) error {
return nil
}
-func getUnrunMigrations(ctx infra.DnoteCtx) ([]int, error) {
+func getUnrunMigrations(ctx context.DnoteCtx) ([]int, error) {
var ret []int
schema, err := readSchema(ctx)
@@ -265,7 +265,7 @@ func getUnrunMigrations(ctx infra.DnoteCtx) ([]int, error) {
return ret, nil
}
-func updateSchemaVersion(ctx infra.DnoteCtx, mID int) error {
+func updateSchemaVersion(ctx context.DnoteCtx, mID int) error {
s, err := readSchema(ctx)
if err != nil {
return errors.Wrap(err, "Failed to read schema")
@@ -470,7 +470,7 @@ var migrateToV8SystemKeyBookMark = "bookmark"
/***** migrations **/
// migrateToV1 deletes YAML archive if exists
-func migrateToV1(ctx infra.DnoteCtx) error {
+func migrateToV1(ctx context.DnoteCtx) error {
yamlPath := fmt.Sprintf("%s/%s", ctx.HomeDir, ".dnote-yaml-archived")
if !utils.FileExists(yamlPath) {
return nil
@@ -483,7 +483,7 @@ func migrateToV1(ctx infra.DnoteCtx) error {
return nil
}
-func migrateToV2(ctx infra.DnoteCtx) error {
+func migrateToV2(ctx context.DnoteCtx) error {
notePath := fmt.Sprintf("%s/dnote", ctx.DnoteDir)
b, err := ioutil.ReadFile(notePath)
@@ -534,7 +534,7 @@ func migrateToV2(ctx infra.DnoteCtx) error {
}
// migrateToV3 generates actions for existing dnote
-func migrateToV3(ctx infra.DnoteCtx) error {
+func migrateToV3(ctx context.DnoteCtx) error {
notePath := fmt.Sprintf("%s/dnote", ctx.DnoteDir)
actionsPath := fmt.Sprintf("%s/actions", ctx.DnoteDir)
@@ -621,7 +621,7 @@ func getEditorCommand() string {
}
}
-func migrateToV4(ctx infra.DnoteCtx) error {
+func migrateToV4(ctx context.DnoteCtx) error {
configPath := fmt.Sprintf("%s/dnoterc", ctx.DnoteDir)
b, err := ioutil.ReadFile(configPath)
@@ -654,7 +654,7 @@ func migrateToV4(ctx infra.DnoteCtx) error {
}
// migrateToV5 migrates actions
-func migrateToV5(ctx infra.DnoteCtx) error {
+func migrateToV5(ctx context.DnoteCtx) error {
actionsPath := fmt.Sprintf("%s/actions", ctx.DnoteDir)
b, err := ioutil.ReadFile(actionsPath)
@@ -719,7 +719,7 @@ func migrateToV5(ctx infra.DnoteCtx) error {
}
// migrateToV6 adds a 'public' field to notes
-func migrateToV6(ctx infra.DnoteCtx) error {
+func migrateToV6(ctx context.DnoteCtx) error {
notePath := fmt.Sprintf("%s/dnote", ctx.DnoteDir)
b, err := ioutil.ReadFile(notePath)
@@ -773,8 +773,8 @@ func migrateToV6(ctx infra.DnoteCtx) error {
// migrateToV7 migrates data of edit_note action to the proper version which is
// EditNoteDataV2. Due to a bug, edit logged actions with schema version '2'
-// but with a data of EditNoteDataV1. https://github.com/dnote/dnote/cli/issues/107
-func migrateToV7(ctx infra.DnoteCtx) error {
+// but with a data of EditNoteDataV1. https://github.com/dnote/dnote/pkg/cli/issues/107
+func migrateToV7(ctx context.DnoteCtx) error {
actionPath := fmt.Sprintf("%s/actions", ctx.DnoteDir)
b, err := ioutil.ReadFile(actionPath)
@@ -838,7 +838,7 @@ func migrateToV7(ctx infra.DnoteCtx) error {
}
// migrateToV8 migrates dnote data to sqlite database
-func migrateToV8(ctx infra.DnoteCtx) error {
+func migrateToV8(ctx context.DnoteCtx) error {
tx, err := ctx.DB.Begin()
if err != nil {
return errors.Wrap(err, "beginning a transaction")
diff --git a/cli/migrate/legacy_test.go b/pkg/cli/migrate/legacy_test.go
similarity index 53%
rename from cli/migrate/legacy_test.go
rename to pkg/cli/migrate/legacy_test.go
index 13100036..012af095 100644
--- a/cli/migrate/legacy_test.go
+++ b/pkg/cli/migrate/legacy_test.go
@@ -27,18 +27,38 @@ import (
"reflect"
"testing"
- "github.com/dnote/dnote/cli/testutils"
- "github.com/dnote/dnote/cli/utils"
+ "github.com/dnote/dnote/pkg/assert"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/testutils"
+ "github.com/dnote/dnote/pkg/cli/utils"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
-func TestMigrateToV1(t *testing.T) {
+func setupEnv(t *testing.T, homeDir string) context.DnoteCtx {
+ dnoteDir := fmt.Sprintf("%s/.dnote", homeDir)
+ if err := os.MkdirAll(dnoteDir, 0755); err != nil {
+ t.Fatal(errors.Wrap(err, "preparing dnote dir"))
+ }
+ return context.DnoteCtx{
+ HomeDir: homeDir,
+ DnoteDir: dnoteDir,
+ }
+}
+
+func teardownEnv(t *testing.T, ctx context.DnoteCtx) {
+ if err := os.RemoveAll(ctx.DnoteDir); err != nil {
+ t.Fatal(errors.Wrap(err, "tearing down the dnote dir"))
+ }
+}
+
+func TestMigrateToV1(t *testing.T) {
t.Run("yaml exists", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ ctx := setupEnv(t, "../tmp")
+ defer teardownEnv(t, ctx)
yamlPath, err := filepath.Abs(filepath.Join(ctx.HomeDir, ".dnote-yaml-archived"))
if err != nil {
@@ -59,8 +79,8 @@ func TestMigrateToV1(t *testing.T) {
t.Run("yaml does not exist", func(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ ctx := setupEnv(t, "../tmp")
+ defer teardownEnv(t, ctx)
yamlPath, err := filepath.Abs(filepath.Join(ctx.HomeDir, ".dnote-yaml-archived"))
if err != nil {
@@ -80,10 +100,10 @@ func TestMigrateToV1(t *testing.T) {
}
func TestMigrateToV2(t *testing.T) {
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ ctx := setupEnv(t, "../tmp")
+ defer teardownEnv(t, ctx)
- testutils.CopyFixture(ctx, "./fixtures/legacy-2-pre-dnote.json", "dnote")
+ testutils.CopyFixture(t, ctx, "./fixtures/legacy-2-pre-dnote.json", "dnote")
// execute
if err := migrateToV2(ctx); err != nil {
@@ -99,25 +119,25 @@ func TestMigrateToV2(t *testing.T) {
}
for _, book := range postDnote {
- testutils.AssertNotEqual(t, book.Name, "", "Book name was not populated")
+ assert.NotEqual(t, book.Name, "", "Book name was not populated")
for _, note := range book.Notes {
if len(note.UUID) == 8 {
t.Errorf("Note UUID was not migrated. It has length of %d", len(note.UUID))
}
- testutils.AssertNotEqual(t, note.AddedOn, int64(0), "AddedOn was not carried over")
- testutils.AssertEqual(t, note.EditedOn, int64(0), "EditedOn was not created properly")
+ assert.NotEqual(t, note.AddedOn, int64(0), "AddedOn was not carried over")
+ assert.Equal(t, note.EditedOn, int64(0), "EditedOn was not created properly")
}
}
}
func TestMigrateToV3(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ ctx := setupEnv(t, "../tmp")
+ defer teardownEnv(t, ctx)
- testutils.CopyFixture(ctx, "./fixtures/legacy-3-pre-dnote.json", "dnote")
+ testutils.CopyFixture(t, ctx, "./fixtures/legacy-3-pre-dnote.json", "dnote")
// execute
if err := migrateToV3(ctx); err != nil {
@@ -137,22 +157,22 @@ func TestMigrateToV3(t *testing.T) {
t.Fatal(errors.Wrap(err, "Failed to unmarshal the actions").Error())
}
- testutils.AssertEqual(t, len(actions), 6, "actions length mismatch")
+ assert.Equal(t, len(actions), 6, "actions length mismatch")
for _, book := range postDnote {
for _, note := range book.Notes {
- testutils.AssertNotEqual(t, note.AddedOn, int64(0), "AddedOn was not carried over")
+ assert.NotEqual(t, note.AddedOn, int64(0), "AddedOn was not carried over")
}
}
}
func TestMigrateToV4(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ ctx := setupEnv(t, "../tmp")
+ defer teardownEnv(t, ctx)
defer os.Setenv("EDITOR", "")
- testutils.CopyFixture(ctx, "./fixtures/legacy-4-pre-dnoterc.yaml", "dnoterc")
+ testutils.CopyFixture(t, ctx, "./fixtures/legacy-4-pre-dnoterc.yaml", "dnoterc")
// execute
os.Setenv("EDITOR", "vim")
@@ -167,16 +187,16 @@ func TestMigrateToV4(t *testing.T) {
t.Fatal(errors.Wrap(err, "Failed to unmarshal the result into Dnote").Error())
}
- testutils.AssertEqual(t, config.APIKey, "Oev6e1082ORasdf9rjkfjkasdfjhgei", "api key mismatch")
- testutils.AssertEqual(t, config.Editor, "vim", "editor mismatch")
+ assert.Equal(t, config.APIKey, "Oev6e1082ORasdf9rjkfjkasdfjhgei", "api key mismatch")
+ assert.Equal(t, config.Editor, "vim", "editor mismatch")
}
func TestMigrateToV5(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ ctx := setupEnv(t, "../tmp")
+ defer teardownEnv(t, ctx)
- testutils.CopyFixture(ctx, "./fixtures/legacy-5-pre-actions.json", "actions")
+ testutils.CopyFixture(t, ctx, "./fixtures/legacy-5-pre-actions.json", "actions")
// execute
if err := migrateToV5(ctx); err != nil {
@@ -201,10 +221,10 @@ func TestMigrateToV5(t *testing.T) {
migrated := migratedActions[idx]
old := oldActions[idx]
- testutils.AssertNotEqual(t, migrated.UUID, "", fmt.Sprintf("uuid mismatch for migrated item with index %d", idx))
- testutils.AssertEqual(t, migrated.Schema, 1, fmt.Sprintf("schema mismatch for migrated item with index %d", idx))
- testutils.AssertEqual(t, migrated.Timestamp, old.Timestamp, fmt.Sprintf("timestamp mismatch for migrated item with index %d", idx))
- testutils.AssertEqual(t, migrated.Type, old.Type, fmt.Sprintf("timestamp mismatch for migrated item with index %d", idx))
+ assert.NotEqual(t, migrated.UUID, "", fmt.Sprintf("uuid mismatch for migrated item with index %d", idx))
+ assert.Equal(t, migrated.Schema, 1, fmt.Sprintf("schema mismatch for migrated item with index %d", idx))
+ assert.Equal(t, migrated.Timestamp, old.Timestamp, fmt.Sprintf("timestamp mismatch for migrated item with index %d", idx))
+ assert.Equal(t, migrated.Type, old.Type, fmt.Sprintf("timestamp mismatch for migrated item with index %d", idx))
switch migrated.Type {
case migrateToV5ActionAddNote:
@@ -216,9 +236,9 @@ func TestMigrateToV5(t *testing.T) {
t.Fatal(errors.Wrap(err, "unmarshalling new data").Error())
}
- testutils.AssertEqual(t, oldData.BookName, migratedData.BookName, fmt.Sprintf("data book_name mismatch for item idx %d", idx))
- testutils.AssertEqual(t, oldData.Content, migratedData.Content, fmt.Sprintf("data content mismatch for item idx %d", idx))
- testutils.AssertEqual(t, oldData.NoteUUID, migratedData.NoteUUID, fmt.Sprintf("data note_uuid mismatch for item idx %d", idx))
+ assert.Equal(t, oldData.BookName, migratedData.BookName, fmt.Sprintf("data book_name mismatch for item idx %d", idx))
+ assert.Equal(t, oldData.Content, migratedData.Content, fmt.Sprintf("data content mismatch for item idx %d", idx))
+ assert.Equal(t, oldData.NoteUUID, migratedData.NoteUUID, fmt.Sprintf("data note_uuid mismatch for item idx %d", idx))
case migrateToV5ActionRemoveNote:
var oldData, migratedData migrateToV5RemoveNoteData
if err := json.Unmarshal(old.Data, &oldData); err != nil {
@@ -228,8 +248,8 @@ func TestMigrateToV5(t *testing.T) {
t.Fatal(errors.Wrap(err, "unmarshalling new data").Error())
}
- testutils.AssertEqual(t, oldData.BookName, migratedData.BookName, fmt.Sprintf("data book_name mismatch for item idx %d", idx))
- testutils.AssertEqual(t, oldData.NoteUUID, migratedData.NoteUUID, fmt.Sprintf("data note_uuid mismatch for item idx %d", idx))
+ assert.Equal(t, oldData.BookName, migratedData.BookName, fmt.Sprintf("data book_name mismatch for item idx %d", idx))
+ assert.Equal(t, oldData.NoteUUID, migratedData.NoteUUID, fmt.Sprintf("data note_uuid mismatch for item idx %d", idx))
case migrateToV5ActionAddBook:
var oldData, migratedData migrateToV5AddBookData
if err := json.Unmarshal(old.Data, &oldData); err != nil {
@@ -239,7 +259,7 @@ func TestMigrateToV5(t *testing.T) {
t.Fatal(errors.Wrap(err, "unmarshalling new data").Error())
}
- testutils.AssertEqual(t, oldData.BookName, migratedData.BookName, fmt.Sprintf("data book_name mismatch for item idx %d", idx))
+ assert.Equal(t, oldData.BookName, migratedData.BookName, fmt.Sprintf("data book_name mismatch for item idx %d", idx))
case migrateToV5ActionRemoveBook:
var oldData, migratedData migrateToV5RemoveBookData
if err := json.Unmarshal(old.Data, &oldData); err != nil {
@@ -249,7 +269,7 @@ func TestMigrateToV5(t *testing.T) {
t.Fatal(errors.Wrap(err, "unmarshalling new data").Error())
}
- testutils.AssertEqual(t, oldData.BookName, migratedData.BookName, fmt.Sprintf("data book_name mismatch for item idx %d", idx))
+ assert.Equal(t, oldData.BookName, migratedData.BookName, fmt.Sprintf("data book_name mismatch for item idx %d", idx))
case migrateToV5ActionEditNote:
var oldData migrateToV5PreEditNoteData
var migratedData migrateToV5PostEditNoteData
@@ -260,20 +280,20 @@ func TestMigrateToV5(t *testing.T) {
t.Fatal(errors.Wrap(err, "unmarshalling new data").Error())
}
- testutils.AssertEqual(t, oldData.NoteUUID, migratedData.NoteUUID, fmt.Sprintf("data note_uuid mismatch for item idx %d", idx))
- testutils.AssertEqual(t, oldData.Content, migratedData.Content, fmt.Sprintf("data content mismatch for item idx %d", idx))
- testutils.AssertEqual(t, oldData.BookName, migratedData.FromBook, "book_name should have been renamed to from_book")
- testutils.AssertEqual(t, migratedData.ToBook, "", "to_book should be empty")
+ assert.Equal(t, oldData.NoteUUID, migratedData.NoteUUID, fmt.Sprintf("data note_uuid mismatch for item idx %d", idx))
+ assert.Equal(t, oldData.Content, migratedData.Content, fmt.Sprintf("data content mismatch for item idx %d", idx))
+ assert.Equal(t, oldData.BookName, migratedData.FromBook, "book_name should have been renamed to from_book")
+ assert.Equal(t, migratedData.ToBook, "", "to_book should be empty")
}
}
}
func TestMigrateToV6(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ ctx := setupEnv(t, "../tmp")
+ defer teardownEnv(t, ctx)
- testutils.CopyFixture(ctx, "./fixtures/legacy-6-pre-dnote.json", "dnote")
+ testutils.CopyFixture(t, ctx, "./fixtures/legacy-6-pre-dnote.json", "dnote")
// execute
if err := migrateToV6(ctx); err != nil {
@@ -287,7 +307,7 @@ func TestMigrateToV6(t *testing.T) {
t.Fatal(errors.Wrap(err, "Failed to unmarshal the result into Dnote").Error())
}
- b = testutils.ReadFileAbs("./fixtures/legacy-6-post-dnote.json")
+ b = utils.ReadFileAbs("./fixtures/legacy-6-post-dnote.json")
var expected migrateToV6PostDnote
if err := json.Unmarshal(b, &expected); err != nil {
t.Fatal(errors.Wrap(err, "Failed to unmarshal the result into Dnote").Error())
@@ -300,10 +320,10 @@ func TestMigrateToV6(t *testing.T) {
func TestMigrateToV7(t *testing.T) {
// set up
- ctx := testutils.InitEnv(t, "../tmp", "../testutils/fixtures/schema.sql", true)
- defer testutils.TeardownEnv(ctx)
+ ctx := setupEnv(t, "../tmp")
+ defer teardownEnv(t, ctx)
- testutils.CopyFixture(ctx, "./fixtures/legacy-7-pre-actions.json", "actions")
+ testutils.CopyFixture(t, ctx, "./fixtures/legacy-7-pre-actions.json", "actions")
// execute
if err := migrateToV7(ctx); err != nil {
@@ -317,32 +337,28 @@ func TestMigrateToV7(t *testing.T) {
t.Fatal(errors.Wrap(err, "unmarshalling the result").Error())
}
- b2 := testutils.ReadFileAbs("./fixtures/legacy-7-post-actions.json")
+ b2 := utils.ReadFileAbs("./fixtures/legacy-7-post-actions.json")
var expected []migrateToV7Action
if err := json.Unmarshal(b, &expected); err != nil {
t.Fatal(errors.Wrap(err, "unmarshalling the result into Dnote").Error())
}
- ok, err := testutils.IsEqualJSON(b, b2)
- if err != nil {
- t.Fatal(errors.Wrap(err, "comparing JSON").Error())
- }
-
- if !ok {
- t.Errorf("Result does not match.\nActual: %+v\nExpected: %+v", got, expected)
- }
+ assert.EqualJSON(t, string(b), string(b2), "Result does not match")
}
func TestMigrateToV8(t *testing.T) {
- ctx := testutils.InitEnv(t, "../tmp", "./fixtures/local-1-pre-schema.sql", false)
- defer testutils.TeardownEnv(ctx)
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-1-pre-schema.sql", SkipMigration: true}
+ db := database.InitTestDB(t, "../tmp/.dnote/dnote-test.db", &opts)
+ defer database.CloseTestDB(t, db)
+
+ ctx := context.DnoteCtx{HomeDir: "../tmp", DnoteDir: "../tmp/.dnote", DB: db}
// set up
- testutils.CopyFixture(ctx, "./fixtures/legacy-8-actions.json", "actions")
- testutils.CopyFixture(ctx, "./fixtures/legacy-8-dnote.json", "dnote")
- testutils.CopyFixture(ctx, "./fixtures/legacy-8-dnoterc.yaml", "dnoterc")
- testutils.CopyFixture(ctx, "./fixtures/legacy-8-schema.yaml", "schema")
- testutils.CopyFixture(ctx, "./fixtures/legacy-8-timestamps.yaml", "timestamps")
+ testutils.CopyFixture(t, ctx, "./fixtures/legacy-8-actions.json", "actions")
+ testutils.CopyFixture(t, ctx, "./fixtures/legacy-8-dnote.json", "dnote")
+ testutils.CopyFixture(t, ctx, "./fixtures/legacy-8-dnoterc.yaml", "dnoterc")
+ testutils.CopyFixture(t, ctx, "./fixtures/legacy-8-schema.yaml", "schema")
+ testutils.CopyFixture(t, ctx, "./fixtures/legacy-8-timestamps.yaml", "timestamps")
// execute
if err := migrateToV8(ctx); err != nil {
@@ -370,7 +386,6 @@ func TestMigrateToV8(t *testing.T) {
}
// 2. test if notes and books are migrated
- db := ctx.DB
var bookCount, noteCount int
err := db.QueryRow("SELECT count(*) FROM books").Scan(&bookCount)
@@ -381,8 +396,8 @@ func TestMigrateToV8(t *testing.T) {
if err != nil {
panic(errors.Wrap(err, "counting notes"))
}
- testutils.AssertEqual(t, bookCount, 2, "book count mismatch")
- testutils.AssertEqual(t, noteCount, 3, "note count mismatch")
+ assert.Equal(t, bookCount, 2, "book count mismatch")
+ assert.Equal(t, noteCount, 3, "note count mismatch")
type bookInfo struct {
label string
@@ -421,34 +436,34 @@ func TestMigrateToV8(t *testing.T) {
panic(errors.Wrap(err, "finding note 3"))
}
- testutils.AssertNotEqual(t, b1.uuid, "", "book 1 uuid should have been generated")
- testutils.AssertEqual(t, b1.label, "js", "book 1 label mismatch")
- testutils.AssertNotEqual(t, b2.uuid, "", "book 2 uuid should have been generated")
- testutils.AssertEqual(t, b2.label, "css", "book 2 label mismatch")
+ assert.NotEqual(t, b1.uuid, "", "book 1 uuid should have been generated")
+ assert.Equal(t, b1.label, "js", "book 1 label mismatch")
+ assert.NotEqual(t, b2.uuid, "", "book 2 uuid should have been generated")
+ assert.Equal(t, b2.label, "css", "book 2 label mismatch")
- testutils.AssertEqual(t, n1.uuid, "d69edb54-5b31-4cdd-a4a5-34f0a0bfa153", "note 1 uuid mismatch")
- testutils.AssertNotEqual(t, n1.id, 0, "note 1 id should have been generated")
- testutils.AssertEqual(t, n1.bookUUID, b2.uuid, "note 1 book_uuid mismatch")
- testutils.AssertEqual(t, n1.content, "css test 1", "note 1 content mismatch")
- testutils.AssertEqual(t, n1.addedOn, int64(1536977237), "note 1 added_on mismatch")
- testutils.AssertEqual(t, n1.editedOn, int64(1536977253), "note 1 edited_on mismatch")
- testutils.AssertEqual(t, n1.public, false, "note 1 public mismatch")
+ assert.Equal(t, n1.uuid, "d69edb54-5b31-4cdd-a4a5-34f0a0bfa153", "note 1 uuid mismatch")
+ assert.NotEqual(t, n1.id, 0, "note 1 id should have been generated")
+ assert.Equal(t, n1.bookUUID, b2.uuid, "note 1 book_uuid mismatch")
+ assert.Equal(t, n1.content, "css test 1", "note 1 content mismatch")
+ assert.Equal(t, n1.addedOn, int64(1536977237), "note 1 added_on mismatch")
+ assert.Equal(t, n1.editedOn, int64(1536977253), "note 1 edited_on mismatch")
+ assert.Equal(t, n1.public, false, "note 1 public mismatch")
- testutils.AssertEqual(t, n2.uuid, "35cbcab1-6a2a-4cc8-97e0-e73bbbd54626", "note 2 uuid mismatch")
- testutils.AssertNotEqual(t, n2.id, 0, "note 2 id should have been generated")
- testutils.AssertEqual(t, n2.bookUUID, b1.uuid, "note 2 book_uuid mismatch")
- testutils.AssertEqual(t, n2.content, "js test 1", "note 2 content mismatch")
- testutils.AssertEqual(t, n2.addedOn, int64(1536977229), "note 2 added_on mismatch")
- testutils.AssertEqual(t, n2.editedOn, int64(0), "note 2 edited_on mismatch")
- testutils.AssertEqual(t, n2.public, false, "note 2 public mismatch")
+ assert.Equal(t, n2.uuid, "35cbcab1-6a2a-4cc8-97e0-e73bbbd54626", "note 2 uuid mismatch")
+ assert.NotEqual(t, n2.id, 0, "note 2 id should have been generated")
+ assert.Equal(t, n2.bookUUID, b1.uuid, "note 2 book_uuid mismatch")
+ assert.Equal(t, n2.content, "js test 1", "note 2 content mismatch")
+ assert.Equal(t, n2.addedOn, int64(1536977229), "note 2 added_on mismatch")
+ assert.Equal(t, n2.editedOn, int64(0), "note 2 edited_on mismatch")
+ assert.Equal(t, n2.public, false, "note 2 public mismatch")
- testutils.AssertEqual(t, n3.uuid, "7c1fcfb2-de8b-4350-88f0-fb3cbaf6630a", "note 3 uuid mismatch")
- testutils.AssertNotEqual(t, n3.id, 0, "note 3 id should have been generated")
- testutils.AssertEqual(t, n3.bookUUID, b1.uuid, "note 3 book_uuid mismatch")
- testutils.AssertEqual(t, n3.content, "js test 2", "note 3 content mismatch")
- testutils.AssertEqual(t, n3.addedOn, int64(1536977230), "note 3 added_on mismatch")
- testutils.AssertEqual(t, n3.editedOn, int64(0), "note 3 edited_on mismatch")
- testutils.AssertEqual(t, n3.public, false, "note 3 public mismatch")
+ assert.Equal(t, n3.uuid, "7c1fcfb2-de8b-4350-88f0-fb3cbaf6630a", "note 3 uuid mismatch")
+ assert.NotEqual(t, n3.id, 0, "note 3 id should have been generated")
+ assert.Equal(t, n3.bookUUID, b1.uuid, "note 3 book_uuid mismatch")
+ assert.Equal(t, n3.content, "js test 2", "note 3 content mismatch")
+ assert.Equal(t, n3.addedOn, int64(1536977230), "note 3 added_on mismatch")
+ assert.Equal(t, n3.editedOn, int64(0), "note 3 edited_on mismatch")
+ assert.Equal(t, n3.public, false, "note 3 public mismatch")
// 3. test if actions are migrated
var actionCount int
@@ -457,7 +472,7 @@ func TestMigrateToV8(t *testing.T) {
panic(errors.Wrap(err, "counting actions"))
}
- testutils.AssertEqual(t, actionCount, 11, "action count mismatch")
+ assert.Equal(t, actionCount, 11, "action count mismatch")
type actionInfo struct {
uuid string
@@ -513,71 +528,71 @@ func TestMigrateToV8(t *testing.T) {
panic(errors.Wrap(err, "finding a11"))
}
- testutils.AssertEqual(t, a1.uuid, "6145c1b7-f286-4d9f-b0f6-00d274baefc6", "action 1 uuid mismatch")
- testutils.AssertEqual(t, a1.schema, 1, "action 1 schema mismatch")
- testutils.AssertEqual(t, a1.actionType, "add_book", "action 1 type mismatch")
- testutils.AssertEqual(t, a1.data, `{"book_name":"js"}`, "action 1 data mismatch")
- testutils.AssertEqual(t, a1.timestamp, 1536977229, "action 1 timestamp mismatch")
+ assert.Equal(t, a1.uuid, "6145c1b7-f286-4d9f-b0f6-00d274baefc6", "action 1 uuid mismatch")
+ assert.Equal(t, a1.schema, 1, "action 1 schema mismatch")
+ assert.Equal(t, a1.actionType, "add_book", "action 1 type mismatch")
+ assert.Equal(t, a1.data, `{"book_name":"js"}`, "action 1 data mismatch")
+ assert.Equal(t, a1.timestamp, 1536977229, "action 1 timestamp mismatch")
- testutils.AssertEqual(t, a2.uuid, "c048a56b-179c-4f31-9995-81e9b32b7dd6", "action 2 uuid mismatch")
- testutils.AssertEqual(t, a2.schema, 2, "action 2 schema mismatch")
- testutils.AssertEqual(t, a2.actionType, "add_note", "action 2 type mismatch")
- testutils.AssertEqual(t, a2.data, `{"note_uuid":"35cbcab1-6a2a-4cc8-97e0-e73bbbd54626","book_name":"js","content":"js test 1","public":false}`, "action 2 data mismatch")
- testutils.AssertEqual(t, a2.timestamp, 1536977229, "action 2 timestamp mismatch")
+ assert.Equal(t, a2.uuid, "c048a56b-179c-4f31-9995-81e9b32b7dd6", "action 2 uuid mismatch")
+ assert.Equal(t, a2.schema, 2, "action 2 schema mismatch")
+ assert.Equal(t, a2.actionType, "add_note", "action 2 type mismatch")
+ assert.Equal(t, a2.data, `{"note_uuid":"35cbcab1-6a2a-4cc8-97e0-e73bbbd54626","book_name":"js","content":"js test 1","public":false}`, "action 2 data mismatch")
+ assert.Equal(t, a2.timestamp, 1536977229, "action 2 timestamp mismatch")
- testutils.AssertEqual(t, a3.uuid, "f557ef48-c304-47dc-adfb-46b7306e701f", "action 3 uuid mismatch")
- testutils.AssertEqual(t, a3.schema, 2, "action 3 schema mismatch")
- testutils.AssertEqual(t, a3.actionType, "add_note", "action 3 type mismatch")
- testutils.AssertEqual(t, a3.data, `{"note_uuid":"7c1fcfb2-de8b-4350-88f0-fb3cbaf6630a","book_name":"js","content":"js test 2","public":false}`, "action 3 data mismatch")
- testutils.AssertEqual(t, a3.timestamp, 1536977230, "action 3 timestamp mismatch")
+ assert.Equal(t, a3.uuid, "f557ef48-c304-47dc-adfb-46b7306e701f", "action 3 uuid mismatch")
+ assert.Equal(t, a3.schema, 2, "action 3 schema mismatch")
+ assert.Equal(t, a3.actionType, "add_note", "action 3 type mismatch")
+ assert.Equal(t, a3.data, `{"note_uuid":"7c1fcfb2-de8b-4350-88f0-fb3cbaf6630a","book_name":"js","content":"js test 2","public":false}`, "action 3 data mismatch")
+ assert.Equal(t, a3.timestamp, 1536977230, "action 3 timestamp mismatch")
- testutils.AssertEqual(t, a4.uuid, "8d79db34-343d-4331-ae5b-24743f17ca7f", "action 4 uuid mismatch")
- testutils.AssertEqual(t, a4.schema, 2, "action 4 schema mismatch")
- testutils.AssertEqual(t, a4.actionType, "add_note", "action 4 type mismatch")
- testutils.AssertEqual(t, a4.data, `{"note_uuid":"b23a88ba-b291-4294-9795-86b394db5dcf","book_name":"js","content":"js test 3","public":false}`, "action 4 data mismatch")
- testutils.AssertEqual(t, a4.timestamp, 1536977234, "action 4 timestamp mismatch")
+ assert.Equal(t, a4.uuid, "8d79db34-343d-4331-ae5b-24743f17ca7f", "action 4 uuid mismatch")
+ assert.Equal(t, a4.schema, 2, "action 4 schema mismatch")
+ assert.Equal(t, a4.actionType, "add_note", "action 4 type mismatch")
+ assert.Equal(t, a4.data, `{"note_uuid":"b23a88ba-b291-4294-9795-86b394db5dcf","book_name":"js","content":"js test 3","public":false}`, "action 4 data mismatch")
+ assert.Equal(t, a4.timestamp, 1536977234, "action 4 timestamp mismatch")
- testutils.AssertEqual(t, a5.uuid, "b9c1ed4a-e6b3-41f2-983b-593ec7b8b7a1", "action 5 uuid mismatch")
- testutils.AssertEqual(t, a5.schema, 1, "action 5 schema mismatch")
- testutils.AssertEqual(t, a5.actionType, "add_book", "action 5 type mismatch")
- testutils.AssertEqual(t, a5.data, `{"book_name":"css"}`, "action 5 data mismatch")
- testutils.AssertEqual(t, a5.timestamp, 1536977237, "action 5 timestamp mismatch")
+ assert.Equal(t, a5.uuid, "b9c1ed4a-e6b3-41f2-983b-593ec7b8b7a1", "action 5 uuid mismatch")
+ assert.Equal(t, a5.schema, 1, "action 5 schema mismatch")
+ assert.Equal(t, a5.actionType, "add_book", "action 5 type mismatch")
+ assert.Equal(t, a5.data, `{"book_name":"css"}`, "action 5 data mismatch")
+ assert.Equal(t, a5.timestamp, 1536977237, "action 5 timestamp mismatch")
- testutils.AssertEqual(t, a6.uuid, "06ed7ef0-f171-4bd7-ae8e-97b5d06a4c49", "action 6 uuid mismatch")
- testutils.AssertEqual(t, a6.schema, 2, "action 6 schema mismatch")
- testutils.AssertEqual(t, a6.actionType, "add_note", "action 6 type mismatch")
- testutils.AssertEqual(t, a6.data, `{"note_uuid":"d69edb54-5b31-4cdd-a4a5-34f0a0bfa153","book_name":"css","content":"js test 3","public":false}`, "action 6 data mismatch")
- testutils.AssertEqual(t, a6.timestamp, 1536977237, "action 6 timestamp mismatch")
+ assert.Equal(t, a6.uuid, "06ed7ef0-f171-4bd7-ae8e-97b5d06a4c49", "action 6 uuid mismatch")
+ assert.Equal(t, a6.schema, 2, "action 6 schema mismatch")
+ assert.Equal(t, a6.actionType, "add_note", "action 6 type mismatch")
+ assert.Equal(t, a6.data, `{"note_uuid":"d69edb54-5b31-4cdd-a4a5-34f0a0bfa153","book_name":"css","content":"js test 3","public":false}`, "action 6 data mismatch")
+ assert.Equal(t, a6.timestamp, 1536977237, "action 6 timestamp mismatch")
- testutils.AssertEqual(t, a7.uuid, "7f173cef-1688-4177-a373-145fcd822b2f", "action 7 uuid mismatch")
- testutils.AssertEqual(t, a7.schema, 2, "action 7 schema mismatch")
- testutils.AssertEqual(t, a7.actionType, "edit_note", "action 7 type mismatch")
- testutils.AssertEqual(t, a7.data, `{"note_uuid":"d69edb54-5b31-4cdd-a4a5-34f0a0bfa153","from_book":"css","to_book":null,"content":"css test 1","public":null}`, "action 7 data mismatch")
- testutils.AssertEqual(t, a7.timestamp, 1536977253, "action 7 timestamp mismatch")
+ assert.Equal(t, a7.uuid, "7f173cef-1688-4177-a373-145fcd822b2f", "action 7 uuid mismatch")
+ assert.Equal(t, a7.schema, 2, "action 7 schema mismatch")
+ assert.Equal(t, a7.actionType, "edit_note", "action 7 type mismatch")
+ assert.Equal(t, a7.data, `{"note_uuid":"d69edb54-5b31-4cdd-a4a5-34f0a0bfa153","from_book":"css","to_book":null,"content":"css test 1","public":null}`, "action 7 data mismatch")
+ assert.Equal(t, a7.timestamp, 1536977253, "action 7 timestamp mismatch")
- testutils.AssertEqual(t, a8.uuid, "64352e08-aa7a-45f4-b760-b3f38b5e11fa", "action 8 uuid mismatch")
- testutils.AssertEqual(t, a8.schema, 1, "action 8 schema mismatch")
- testutils.AssertEqual(t, a8.actionType, "add_book", "action 8 type mismatch")
- testutils.AssertEqual(t, a8.data, `{"book_name":"sql"}`, "action 8 data mismatch")
- testutils.AssertEqual(t, a8.timestamp, 1536977261, "action 8 timestamp mismatch")
+ assert.Equal(t, a8.uuid, "64352e08-aa7a-45f4-b760-b3f38b5e11fa", "action 8 uuid mismatch")
+ assert.Equal(t, a8.schema, 1, "action 8 schema mismatch")
+ assert.Equal(t, a8.actionType, "add_book", "action 8 type mismatch")
+ assert.Equal(t, a8.data, `{"book_name":"sql"}`, "action 8 data mismatch")
+ assert.Equal(t, a8.timestamp, 1536977261, "action 8 timestamp mismatch")
- testutils.AssertEqual(t, a9.uuid, "82e20a12-bda8-45f7-ac42-b453b6daa5ec", "action 9 uuid mismatch")
- testutils.AssertEqual(t, a9.schema, 2, "action 9 schema mismatch")
- testutils.AssertEqual(t, a9.actionType, "add_note", "action 9 type mismatch")
- testutils.AssertEqual(t, a9.data, `{"note_uuid":"2f47d390-685b-4b84-89ac-704c6fb8d3fb","book_name":"sql","content":"blah","public":false}`, "action 9 data mismatch")
- testutils.AssertEqual(t, a9.timestamp, 1536977261, "action 9 timestamp mismatch")
+ assert.Equal(t, a9.uuid, "82e20a12-bda8-45f7-ac42-b453b6daa5ec", "action 9 uuid mismatch")
+ assert.Equal(t, a9.schema, 2, "action 9 schema mismatch")
+ assert.Equal(t, a9.actionType, "add_note", "action 9 type mismatch")
+ assert.Equal(t, a9.data, `{"note_uuid":"2f47d390-685b-4b84-89ac-704c6fb8d3fb","book_name":"sql","content":"blah","public":false}`, "action 9 data mismatch")
+ assert.Equal(t, a9.timestamp, 1536977261, "action 9 timestamp mismatch")
- testutils.AssertEqual(t, a10.uuid, "a29055f4-ace4-44fd-8800-3396edbccaef", "action 10 uuid mismatch")
- testutils.AssertEqual(t, a10.schema, 1, "action 10 schema mismatch")
- testutils.AssertEqual(t, a10.actionType, "remove_book", "action 10 type mismatch")
- testutils.AssertEqual(t, a10.data, `{"book_name":"sql"}`, "action 10 data mismatch")
- testutils.AssertEqual(t, a10.timestamp, 1536977268, "action 10 timestamp mismatch")
+ assert.Equal(t, a10.uuid, "a29055f4-ace4-44fd-8800-3396edbccaef", "action 10 uuid mismatch")
+ assert.Equal(t, a10.schema, 1, "action 10 schema mismatch")
+ assert.Equal(t, a10.actionType, "remove_book", "action 10 type mismatch")
+ assert.Equal(t, a10.data, `{"book_name":"sql"}`, "action 10 data mismatch")
+ assert.Equal(t, a10.timestamp, 1536977268, "action 10 timestamp mismatch")
- testutils.AssertEqual(t, a11.uuid, "871a5562-1bd0-43c1-b550-5bbb727ac7c4", "action 11 uuid mismatch")
- testutils.AssertEqual(t, a11.schema, 1, "action 11 schema mismatch")
- testutils.AssertEqual(t, a11.actionType, "remove_note", "action 11 type mismatch")
- testutils.AssertEqual(t, a11.data, `{"note_uuid":"b23a88ba-b291-4294-9795-86b394db5dcf","book_name":"js"}`, "action 11 data mismatch")
- testutils.AssertEqual(t, a11.timestamp, 1536977274, "action 11 timestamp mismatch")
+ assert.Equal(t, a11.uuid, "871a5562-1bd0-43c1-b550-5bbb727ac7c4", "action 11 uuid mismatch")
+ assert.Equal(t, a11.schema, 1, "action 11 schema mismatch")
+ assert.Equal(t, a11.actionType, "remove_note", "action 11 type mismatch")
+ assert.Equal(t, a11.data, `{"note_uuid":"b23a88ba-b291-4294-9795-86b394db5dcf","book_name":"js"}`, "action 11 data mismatch")
+ assert.Equal(t, a11.timestamp, 1536977274, "action 11 timestamp mismatch")
// 3. test if system is migrated
var systemCount int
@@ -586,7 +601,7 @@ func TestMigrateToV8(t *testing.T) {
panic(errors.Wrap(err, "counting system"))
}
- testutils.AssertEqual(t, systemCount, 3, "action count mismatch")
+ assert.Equal(t, systemCount, 3, "action count mismatch")
var lastUpgrade, lastAction, bookmark int
err = db.QueryRow("SELECT value FROM system WHERE key = ?", "last_upgrade").Scan(&lastUpgrade)
@@ -602,7 +617,7 @@ func TestMigrateToV8(t *testing.T) {
panic(errors.Wrap(err, "finding bookmark"))
}
- testutils.AssertEqual(t, lastUpgrade, 1536977220, "last_upgrade mismatch")
- testutils.AssertEqual(t, lastAction, 1536977274, "last_action mismatch")
- testutils.AssertEqual(t, bookmark, 9, "bookmark mismatch")
+ assert.Equal(t, lastUpgrade, 1536977220, "last_upgrade mismatch")
+ assert.Equal(t, lastAction, 1536977274, "last_action mismatch")
+ assert.Equal(t, bookmark, 9, "bookmark mismatch")
}
diff --git a/cli/migrate/migrate.go b/pkg/cli/migrate/migrate.go
similarity index 84%
rename from cli/migrate/migrate.go
rename to pkg/cli/migrate/migrate.go
index f8276cd9..edf0c893 100644
--- a/cli/migrate/migrate.go
+++ b/pkg/cli/migrate/migrate.go
@@ -20,8 +20,9 @@ package migrate
import (
"database/sql"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/log"
"github.com/pkg/errors"
)
@@ -52,7 +53,7 @@ var RemoteSequence = []migration{
rm1,
}
-func initSchema(ctx infra.DnoteCtx, schemaKey string) (int, error) {
+func initSchema(ctx context.DnoteCtx, schemaKey string) (int, error) {
// schemaVersion is the index of the latest run migration in the sequence
schemaVersion := 0
@@ -67,17 +68,17 @@ func initSchema(ctx infra.DnoteCtx, schemaKey string) (int, error) {
func getSchemaKey(mode int) (string, error) {
if mode == LocalMode {
- return infra.SystemSchema, nil
+ return consts.SystemSchema, nil
}
if mode == RemoteMode {
- return infra.SystemRemoteSchema, nil
+ return consts.SystemRemoteSchema, nil
}
return "", errors.Errorf("unsupported migration type '%d'", mode)
}
-func getSchema(ctx infra.DnoteCtx, schemaKey string) (int, error) {
+func getSchema(ctx context.DnoteCtx, schemaKey string) (int, error) {
var ret int
db := ctx.DB
@@ -95,7 +96,7 @@ func getSchema(ctx infra.DnoteCtx, schemaKey string) (int, error) {
return ret, nil
}
-func execute(ctx infra.DnoteCtx, m migration, schemaKey string) error {
+func execute(ctx context.DnoteCtx, m migration, schemaKey string) error {
log.Debug("running migration %s\n", m.name)
tx, err := ctx.DB.Begin()
@@ -128,7 +129,7 @@ func execute(ctx infra.DnoteCtx, m migration, schemaKey string) error {
}
// Run performs unrun migrations
-func Run(ctx infra.DnoteCtx, migrations []migration, mode int) error {
+func Run(ctx context.DnoteCtx, migrations []migration, mode int) error {
schemaKey, err := getSchemaKey(mode)
if err != nil {
return errors.Wrap(err, "getting schema key")
@@ -139,7 +140,7 @@ func Run(ctx infra.DnoteCtx, migrations []migration, mode int) error {
return errors.Wrap(err, "getting the current schema")
}
- log.Debug("current schema: %s %d of %d\n", infra.SystemSchema, schema, len(migrations))
+ log.Debug("current schema: %s %d of %d\n", consts.SystemSchema, schema, len(migrations))
toRun := migrations[schema:]
diff --git a/pkg/cli/migrate/migrate_test.go b/pkg/cli/migrate/migrate_test.go
new file mode 100644
index 00000000..cdb4137b
--- /dev/null
+++ b/pkg/cli/migrate/migrate_test.go
@@ -0,0 +1,1134 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+package migrate
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+ "time"
+
+ "github.com/dnote/actions"
+ "github.com/dnote/dnote/pkg/assert"
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/testutils"
+ "github.com/dnote/dnote/pkg/cli/utils"
+ "github.com/pkg/errors"
+)
+
+func TestExecute_bump_schema(t *testing.T) {
+ testCases := []struct {
+ schemaKey string
+ }{
+ {
+ schemaKey: consts.SystemSchema,
+ },
+ {
+ schemaKey: consts.SystemRemoteSchema,
+ },
+ }
+
+ for _, tc := range testCases {
+ func() {
+ // set up
+ opts := database.TestDBOptions{SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ database.MustExec(t, "inserting a schema", db, "INSERT INTO system (key, value) VALUES (?, ?)", tc.schemaKey, 8)
+
+ m1 := migration{
+ name: "noop",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ return nil
+ },
+ }
+ m2 := migration{
+ name: "noop",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ return nil
+ },
+ }
+
+ // execute
+ err := execute(ctx, m1, tc.schemaKey)
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "failed to execute"))
+ }
+ err = execute(ctx, m2, tc.schemaKey)
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "failed to execute"))
+ }
+
+ // test
+ var schema int
+ database.MustScan(t, "getting schema", db.QueryRow("SELECT value FROM system WHERE key = ?", tc.schemaKey), &schema)
+ assert.Equal(t, schema, 10, "schema was not incremented properly")
+ }()
+ }
+}
+
+func TestRun_nonfresh(t *testing.T) {
+ testCases := []struct {
+ mode int
+ schemaKey string
+ }{
+ {
+ mode: LocalMode,
+ schemaKey: consts.SystemSchema,
+ },
+ {
+ mode: RemoteMode,
+ schemaKey: consts.SystemRemoteSchema,
+ },
+ }
+
+ for _, tc := range testCases {
+ func() {
+ // set up
+ opts := database.TestDBOptions{SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+ database.MustExec(t, "inserting a schema", db, "INSERT INTO system (key, value) VALUES (?, ?)", tc.schemaKey, 2)
+ database.MustExec(t, "creating a temporary table for testing", db,
+ "CREATE TABLE migrate_run_test ( name string )")
+
+ sequence := []migration{
+ migration{
+ name: "v1",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ database.MustExec(t, "marking v1 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v1")
+ return nil
+ },
+ },
+ migration{
+ name: "v2",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ database.MustExec(t, "marking v2 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v2")
+ return nil
+ },
+ },
+ migration{
+ name: "v3",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ database.MustExec(t, "marking v3 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v3")
+ return nil
+ },
+ },
+ migration{
+ name: "v4",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ database.MustExec(t, "marking v4 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v4")
+ return nil
+ },
+ },
+ }
+
+ // execute
+ err := Run(ctx, sequence, tc.mode)
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ // test
+ var schema int
+ database.MustScan(t, fmt.Sprintf("getting schema for %s", tc.schemaKey), db.QueryRow("SELECT value FROM system WHERE key = ?", tc.schemaKey), &schema)
+ assert.Equal(t, schema, 4, fmt.Sprintf("schema was not updated for %s", tc.schemaKey))
+
+ var testRunCount int
+ database.MustScan(t, "counting test runs", db.QueryRow("SELECT count(*) FROM migrate_run_test"), &testRunCount)
+ assert.Equal(t, testRunCount, 2, "test run count mismatch")
+
+ var testRun1, testRun2 string
+ database.MustScan(t, "finding test run 1", db.QueryRow("SELECT name FROM migrate_run_test WHERE name = ?", "v3"), &testRun1)
+ database.MustScan(t, "finding test run 2", db.QueryRow("SELECT name FROM migrate_run_test WHERE name = ?", "v4"), &testRun2)
+ }()
+ }
+}
+
+func TestRun_fresh(t *testing.T) {
+ testCases := []struct {
+ mode int
+ schemaKey string
+ }{
+ {
+ mode: LocalMode,
+ schemaKey: consts.SystemSchema,
+ },
+ {
+ mode: RemoteMode,
+ schemaKey: consts.SystemRemoteSchema,
+ },
+ }
+
+ for _, tc := range testCases {
+ func() {
+ // set up
+ opts := database.TestDBOptions{SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ database.MustExec(t, "creating a temporary table for testing", db,
+ "CREATE TABLE migrate_run_test ( name string )")
+
+ sequence := []migration{
+ migration{
+ name: "v1",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ database.MustExec(t, "marking v1 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v1")
+ return nil
+ },
+ },
+ migration{
+ name: "v2",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ database.MustExec(t, "marking v2 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v2")
+ return nil
+ },
+ },
+ migration{
+ name: "v3",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ database.MustExec(t, "marking v3 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v3")
+ return nil
+ },
+ },
+ }
+
+ // execute
+ err := Run(ctx, sequence, tc.mode)
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ // test
+ var schema int
+ database.MustScan(t, "getting schema", db.QueryRow("SELECT value FROM system WHERE key = ?", tc.schemaKey), &schema)
+ assert.Equal(t, schema, 3, "schema was not updated")
+
+ var testRunCount int
+ database.MustScan(t, "counting test runs", db.QueryRow("SELECT count(*) FROM migrate_run_test"), &testRunCount)
+ assert.Equal(t, testRunCount, 3, "test run count mismatch")
+
+ var testRun1, testRun2, testRun3 string
+ database.MustScan(t, "finding test run 1", db.QueryRow("SELECT name FROM migrate_run_test WHERE name = ?", "v1"), &testRun1)
+ database.MustScan(t, "finding test run 2", db.QueryRow("SELECT name FROM migrate_run_test WHERE name = ?", "v2"), &testRun2)
+ database.MustScan(t, "finding test run 2", db.QueryRow("SELECT name FROM migrate_run_test WHERE name = ?", "v3"), &testRun3)
+ }()
+ }
+}
+
+func TestRun_up_to_date(t *testing.T) {
+ testCases := []struct {
+ mode int
+ schemaKey string
+ }{
+ {
+ mode: LocalMode,
+ schemaKey: consts.SystemSchema,
+ },
+ {
+ mode: RemoteMode,
+ schemaKey: consts.SystemRemoteSchema,
+ },
+ }
+
+ for _, tc := range testCases {
+ func() {
+ // set up
+ opts := database.TestDBOptions{SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ database.MustExec(t, "creating a temporary table for testing", db,
+ "CREATE TABLE migrate_run_test ( name string )")
+
+ database.MustExec(t, "inserting a schema", db, "INSERT INTO system (key, value) VALUES (?, ?)", tc.schemaKey, 3)
+
+ sequence := []migration{
+ migration{
+ name: "v1",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ database.MustExec(t, "marking v1 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v1")
+ return nil
+ },
+ },
+ migration{
+ name: "v2",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ database.MustExec(t, "marking v2 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v2")
+ return nil
+ },
+ },
+ migration{
+ name: "v3",
+ run: func(ctx context.DnoteCtx, db *database.DB) error {
+ database.MustExec(t, "marking v3 completed", db, "INSERT INTO migrate_run_test (name) VALUES (?)", "v3")
+ return nil
+ },
+ },
+ }
+
+ // execute
+ err := Run(ctx, sequence, tc.mode)
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ // test
+ var schema int
+ database.MustScan(t, "getting schema", db.QueryRow("SELECT value FROM system WHERE key = ?", tc.schemaKey), &schema)
+ assert.Equal(t, schema, 3, "schema was not updated")
+
+ var testRunCount int
+ database.MustScan(t, "counting test runs", db.QueryRow("SELECT count(*) FROM migrate_run_test"), &testRunCount)
+ assert.Equal(t, testRunCount, 0, "test run count mismatch")
+ }()
+ }
+}
+
+func TestLocalMigration1(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-1-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+ data := testutils.MustMarshalJSON(t, actions.AddBookDataV1{BookName: "js"})
+ a1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting action", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a1UUID, 1, "add_book", string(data), 1537829463)
+
+ data = testutils.MustMarshalJSON(t, actions.EditNoteDataV1{NoteUUID: "note-1-uuid", FromBook: "js", ToBook: "", Content: "note 1"})
+ a2UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting action", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a2UUID, 1, "edit_note", string(data), 1537829463)
+
+ data = testutils.MustMarshalJSON(t, actions.EditNoteDataV1{NoteUUID: "note-2-uuid", FromBook: "js", ToBook: "", Content: "note 2"})
+ a3UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting action", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a3UUID, 1, "edit_note", string(data), 1537829463)
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm1.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+ var actionCount int
+ database.MustScan(t, "counting actions", db.QueryRow("SELECT count(*) FROM actions"), &actionCount)
+ assert.Equal(t, actionCount, 3, "action count mismatch")
+
+ var a1, a2, a3 actions.Action
+ database.MustScan(t, "getting action 1", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a1UUID),
+ &a1.Schema, &a1.Type, &a1.Data, &a1.Timestamp)
+ database.MustScan(t, "getting action 2", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a2UUID),
+ &a2.Schema, &a2.Type, &a2.Data, &a2.Timestamp)
+ database.MustScan(t, "getting action 3", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a3UUID),
+ &a3.Schema, &a3.Type, &a3.Data, &a3.Timestamp)
+
+ var a1Data actions.AddBookDataV1
+ var a2Data, a3Data actions.EditNoteDataV3
+ testutils.MustUnmarshalJSON(t, a1.Data, &a1Data)
+ testutils.MustUnmarshalJSON(t, a2.Data, &a2Data)
+ testutils.MustUnmarshalJSON(t, a3.Data, &a3Data)
+
+ assert.Equal(t, a1.Schema, 1, "a1 schema mismatch")
+ assert.Equal(t, a1.Type, "add_book", "a1 type mismatch")
+ assert.Equal(t, a1.Timestamp, int64(1537829463), "a1 timestamp mismatch")
+ assert.Equal(t, a1Data.BookName, "js", "a1 data book_name mismatch")
+
+ assert.Equal(t, a2.Schema, 3, "a2 schema mismatch")
+ assert.Equal(t, a2.Type, "edit_note", "a2 type mismatch")
+ assert.Equal(t, a2.Timestamp, int64(1537829463), "a2 timestamp mismatch")
+ assert.Equal(t, a2Data.NoteUUID, "note-1-uuid", "a2 data note_uuid mismatch")
+ assert.Equal(t, a2Data.BookName, (*string)(nil), "a2 data book_name mismatch")
+ assert.Equal(t, *a2Data.Content, "note 1", "a2 data content mismatch")
+ assert.Equal(t, *a2Data.Public, false, "a2 data public mismatch")
+
+ assert.Equal(t, a3.Schema, 3, "a3 schema mismatch")
+ assert.Equal(t, a3.Type, "edit_note", "a3 type mismatch")
+ assert.Equal(t, a3.Timestamp, int64(1537829463), "a3 timestamp mismatch")
+ assert.Equal(t, a3Data.NoteUUID, "note-2-uuid", "a3 data note_uuid mismatch")
+ assert.Equal(t, a3Data.BookName, (*string)(nil), "a3 data book_name mismatch")
+ assert.Equal(t, *a3Data.Content, "note 2", "a3 data content mismatch")
+ assert.Equal(t, *a3Data.Public, false, "a3 data public mismatch")
+}
+
+func TestLocalMigration2(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-1-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+ c1 := "note 1 - v1"
+ c2 := "note 1 - v2"
+ css := "css"
+
+ b1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting css book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "css")
+
+ data := testutils.MustMarshalJSON(t, actions.AddNoteDataV2{NoteUUID: "note-1-uuid", BookName: "js", Content: "note 1", Public: false})
+ a1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting action", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a1UUID, 2, "add_note", string(data), 1537829463)
+
+ data = testutils.MustMarshalJSON(t, actions.EditNoteDataV2{NoteUUID: "note-1-uuid", FromBook: "js", ToBook: nil, Content: &c1, Public: nil})
+ a2UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting action", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a2UUID, 2, "edit_note", string(data), 1537829463)
+
+ data = testutils.MustMarshalJSON(t, actions.EditNoteDataV2{NoteUUID: "note-1-uuid", FromBook: "js", ToBook: &css, Content: &c2, Public: nil})
+ a3UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting action", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a3UUID, 2, "edit_note", string(data), 1537829463)
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm2.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+ var actionCount int
+ database.MustScan(t, "counting actions", db.QueryRow("SELECT count(*) FROM actions"), &actionCount)
+ assert.Equal(t, actionCount, 3, "action count mismatch")
+
+ var a1, a2, a3 actions.Action
+ database.MustScan(t, "getting action 1", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a1UUID),
+ &a1.Schema, &a1.Type, &a1.Data, &a1.Timestamp)
+ database.MustScan(t, "getting action 2", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a2UUID),
+ &a2.Schema, &a2.Type, &a2.Data, &a2.Timestamp)
+ database.MustScan(t, "getting action 3", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a3UUID),
+ &a3.Schema, &a3.Type, &a3.Data, &a3.Timestamp)
+
+ var a1Data actions.AddNoteDataV2
+ var a2Data, a3Data actions.EditNoteDataV3
+ testutils.MustUnmarshalJSON(t, a1.Data, &a1Data)
+ testutils.MustUnmarshalJSON(t, a2.Data, &a2Data)
+ testutils.MustUnmarshalJSON(t, a3.Data, &a3Data)
+
+ assert.Equal(t, a1.Schema, 2, "a1 schema mismatch")
+ assert.Equal(t, a1.Type, "add_note", "a1 type mismatch")
+ assert.Equal(t, a1.Timestamp, int64(1537829463), "a1 timestamp mismatch")
+ assert.Equal(t, a1Data.NoteUUID, "note-1-uuid", "a1 data note_uuid mismatch")
+ assert.Equal(t, a1Data.BookName, "js", "a1 data book_name mismatch")
+ assert.Equal(t, a1Data.Public, false, "a1 data public mismatch")
+
+ assert.Equal(t, a2.Schema, 3, "a2 schema mismatch")
+ assert.Equal(t, a2.Type, "edit_note", "a2 type mismatch")
+ assert.Equal(t, a2.Timestamp, int64(1537829463), "a2 timestamp mismatch")
+ assert.Equal(t, a2Data.NoteUUID, "note-1-uuid", "a2 data note_uuid mismatch")
+ assert.Equal(t, a2Data.BookName, (*string)(nil), "a2 data book_name mismatch")
+ assert.Equal(t, *a2Data.Content, c1, "a2 data content mismatch")
+ assert.Equal(t, a2Data.Public, (*bool)(nil), "a2 data public mismatch")
+
+ assert.Equal(t, a3.Schema, 3, "a3 schema mismatch")
+ assert.Equal(t, a3.Type, "edit_note", "a3 type mismatch")
+ assert.Equal(t, a3.Timestamp, int64(1537829463), "a3 timestamp mismatch")
+ assert.Equal(t, a3Data.NoteUUID, "note-1-uuid", "a3 data note_uuid mismatch")
+ assert.Equal(t, *a3Data.BookName, "css", "a3 data book_name mismatch")
+ assert.Equal(t, *a3Data.Content, c2, "a3 data content mismatch")
+ assert.Equal(t, a3Data.Public, (*bool)(nil), "a3 data public mismatch")
+}
+
+func TestLocalMigration3(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-1-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+ data := testutils.MustMarshalJSON(t, actions.AddNoteDataV2{NoteUUID: "note-1-uuid", BookName: "js", Content: "note 1", Public: false})
+ a1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting action", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a1UUID, 2, "add_note", string(data), 1537829463)
+
+ data = testutils.MustMarshalJSON(t, actions.RemoveNoteDataV1{NoteUUID: "note-1-uuid", BookName: "js"})
+ a2UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting action", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a2UUID, 1, "remove_note", string(data), 1537829463)
+
+ data = testutils.MustMarshalJSON(t, actions.RemoveNoteDataV1{NoteUUID: "note-2-uuid", BookName: "js"})
+ a3UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting action", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a3UUID, 1, "remove_note", string(data), 1537829463)
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm3.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+ var actionCount int
+ database.MustScan(t, "counting actions", db.QueryRow("SELECT count(*) FROM actions"), &actionCount)
+ assert.Equal(t, actionCount, 3, "action count mismatch")
+
+ var a1, a2, a3 actions.Action
+ database.MustScan(t, "getting action 1", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a1UUID),
+ &a1.Schema, &a1.Type, &a1.Data, &a1.Timestamp)
+ database.MustScan(t, "getting action 2", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a2UUID),
+ &a2.Schema, &a2.Type, &a2.Data, &a2.Timestamp)
+ database.MustScan(t, "getting action 3", db.QueryRow("SELECT schema, type, data, timestamp FROM actions WHERE uuid = ?", a3UUID),
+ &a3.Schema, &a3.Type, &a3.Data, &a3.Timestamp)
+
+ var a1Data actions.AddNoteDataV2
+ var a2Data, a3Data actions.RemoveNoteDataV2
+ testutils.MustUnmarshalJSON(t, a1.Data, &a1Data)
+ testutils.MustUnmarshalJSON(t, a2.Data, &a2Data)
+ testutils.MustUnmarshalJSON(t, a3.Data, &a3Data)
+
+ assert.Equal(t, a1.Schema, 2, "a1 schema mismatch")
+ assert.Equal(t, a1.Type, "add_note", "a1 type mismatch")
+ assert.Equal(t, a1.Timestamp, int64(1537829463), "a1 timestamp mismatch")
+ assert.Equal(t, a1Data.NoteUUID, "note-1-uuid", "a1 data note_uuid mismatch")
+ assert.Equal(t, a1Data.BookName, "js", "a1 data book_name mismatch")
+ assert.Equal(t, a1Data.Content, "note 1", "a1 data content mismatch")
+ assert.Equal(t, a1Data.Public, false, "a1 data public mismatch")
+
+ assert.Equal(t, a2.Schema, 2, "a2 schema mismatch")
+ assert.Equal(t, a2.Type, "remove_note", "a2 type mismatch")
+ assert.Equal(t, a2.Timestamp, int64(1537829463), "a2 timestamp mismatch")
+ assert.Equal(t, a2Data.NoteUUID, "note-1-uuid", "a2 data note_uuid mismatch")
+
+ assert.Equal(t, a3.Schema, 2, "a3 schema mismatch")
+ assert.Equal(t, a3.Type, "remove_note", "a3 type mismatch")
+ assert.Equal(t, a3.Timestamp, int64(1537829463), "a3 timestamp mismatch")
+ assert.Equal(t, a3Data.NoteUUID, "note-2-uuid", "a3 data note_uuid mismatch")
+}
+
+func TestLocalMigration4(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-1-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ b1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting css book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "css")
+ n1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting css note", db, "INSERT INTO notes (uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?)", n1UUID, b1UUID, "n1 content", time.Now().UnixNano())
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm4.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+ var n1Dirty, b1Dirty bool
+ var n1Deleted, b1Deleted bool
+ var n1USN, b1USN int
+ database.MustScan(t, "scanning the newly added dirty flag of n1", db.QueryRow("SELECT dirty, deleted, usn FROM notes WHERE uuid = ?", n1UUID), &n1Dirty, &n1Deleted, &n1USN)
+ database.MustScan(t, "scanning the newly added dirty flag of b1", db.QueryRow("SELECT dirty, deleted, usn FROM books WHERE uuid = ?", b1UUID), &b1Dirty, &b1Deleted, &b1USN)
+
+ assert.Equal(t, n1Dirty, false, "n1 dirty flag should be false by default")
+ assert.Equal(t, b1Dirty, false, "b1 dirty flag should be false by default")
+
+ assert.Equal(t, n1Deleted, false, "n1 deleted flag should be false by default")
+ assert.Equal(t, b1Deleted, false, "b1 deleted flag should be false by default")
+
+ assert.Equal(t, n1USN, 0, "n1 usn flag should be 0 by default")
+ assert.Equal(t, b1USN, 0, "b1 usn flag should be 0 by default")
+}
+
+func TestLocalMigration5(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-5-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ b1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting css book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "css")
+ b2UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting js book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "js")
+
+ n1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting css note", db, "INSERT INTO notes (uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?)", n1UUID, b1UUID, "n1 content", time.Now().UnixNano())
+ n2UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting css note", db, "INSERT INTO notes (uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?)", n2UUID, b1UUID, "n2 content", time.Now().UnixNano())
+ n3UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting css note", db, "INSERT INTO notes (uuid, book_uuid, content, added_on) VALUES (?, ?, ?, ?)", n3UUID, b1UUID, "n3 content", time.Now().UnixNano())
+
+ data := testutils.MustMarshalJSON(t, actions.AddBookDataV1{BookName: "js"})
+ database.MustExec(t, "inserting a1", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", "a1-uuid", 1, "add_book", string(data), 1537829463)
+
+ data = testutils.MustMarshalJSON(t, actions.AddNoteDataV2{NoteUUID: n1UUID, BookName: "css", Content: "n1 content", Public: false})
+ database.MustExec(t, "inserting a2", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", "a2-uuid", 1, "add_note", string(data), 1537829463)
+
+ updatedContent := "updated content"
+ data = testutils.MustMarshalJSON(t, actions.EditNoteDataV3{NoteUUID: n2UUID, BookName: (*string)(nil), Content: &updatedContent, Public: (*bool)(nil)})
+ database.MustExec(t, "inserting a3", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", "a3-uuid", 1, "edit_note", string(data), 1537829463)
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm5.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+ var b1Dirty, b2Dirty, n1Dirty, n2Dirty, n3Dirty bool
+ database.MustScan(t, "scanning the newly added dirty flag of b1", db.QueryRow("SELECT dirty FROM books WHERE uuid = ?", b1UUID), &b1Dirty)
+ database.MustScan(t, "scanning the newly added dirty flag of b2", db.QueryRow("SELECT dirty FROM books WHERE uuid = ?", b2UUID), &b2Dirty)
+ database.MustScan(t, "scanning the newly added dirty flag of n1", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", n1UUID), &n1Dirty)
+ database.MustScan(t, "scanning the newly added dirty flag of n2", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", n2UUID), &n2Dirty)
+ database.MustScan(t, "scanning the newly added dirty flag of n3", db.QueryRow("SELECT dirty FROM notes WHERE uuid = ?", n3UUID), &n3Dirty)
+
+ assert.Equal(t, b1Dirty, false, "b1 dirty flag should be false by default")
+ assert.Equal(t, b2Dirty, true, "b2 dirty flag should be false by default")
+ assert.Equal(t, n1Dirty, true, "n1 dirty flag should be false by default")
+ assert.Equal(t, n2Dirty, true, "n2 dirty flag should be false by default")
+ assert.Equal(t, n3Dirty, false, "n3 dirty flag should be false by default")
+}
+
+func TestLocalMigration6(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-5-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ data := testutils.MustMarshalJSON(t, actions.AddBookDataV1{BookName: "js"})
+ a1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting action", db,
+ "INSERT INTO actions (uuid, schema, type, data, timestamp) VALUES (?, ?, ?, ?, ?)", a1UUID, 1, "add_book", string(data), 1537829463)
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm5.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+ var count int
+ err = db.QueryRow("SELECT name FROM sqlite_master WHERE type='table' AND name = ?;", "actions").Scan(&count)
+ assert.Equal(t, count, 0, "actions table should have been deleted")
+}
+
+func TestLocalMigration7_trash(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-7-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ b1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting trash book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "trash")
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm7.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+ var b1Label string
+ var b1Dirty bool
+ database.MustScan(t, "scanning b1 label", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b1UUID), &b1Label, &b1Dirty)
+ assert.Equal(t, b1Label, "trash (2)", "b1 label was not migrated")
+ assert.Equal(t, b1Dirty, true, "b1 was not marked dirty")
+}
+
+func TestLocalMigration7_conflicts(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-7-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ b1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "conflicts")
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm7.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+ var b1Label string
+ var b1Dirty bool
+ database.MustScan(t, "scanning b1 label", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b1UUID), &b1Label, &b1Dirty)
+ assert.Equal(t, b1Label, "conflicts (2)", "b1 label was not migrated")
+ assert.Equal(t, b1Dirty, true, "b1 was not marked dirty")
+}
+
+func TestLocalMigration7_conflicts_dup(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-7-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ b1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "conflicts")
+ b2UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "conflicts (2)")
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm7.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+ var b1Label, b2Label string
+ var b1Dirty, b2Dirty bool
+ database.MustScan(t, "scanning b1 label", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b1UUID), &b1Label, &b1Dirty)
+ database.MustScan(t, "scanning b2 label", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b2UUID), &b2Label, &b2Dirty)
+ assert.Equal(t, b1Label, "conflicts (3)", "b1 label was not migrated")
+ assert.Equal(t, b2Label, "conflicts (2)", "b1 label was not migrated")
+ assert.Equal(t, b1Dirty, true, "b1 was not marked dirty")
+ assert.Equal(t, b2Dirty, false, "b2 should not have been marked dirty")
+}
+
+func TestLocalMigration8(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-8-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ b1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1")
+
+ n1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting n1", db, `INSERT INTO notes
+ (id, uuid, book_uuid, content, added_on, edited_on, public, dirty, usn, deleted) VALUES
+ (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, 1, n1UUID, b1UUID, "n1 Body", 1, 2, true, true, 20, false)
+ n2UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting n2", db, `INSERT INTO notes
+ (id, uuid, book_uuid, content, added_on, edited_on, public, dirty, usn, deleted) VALUES
+ (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, 2, n2UUID, b1UUID, "", 3, 4, false, true, 21, true)
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm8.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+ var n1BookUUID, n1Body string
+ var n1AddedOn, n1EditedOn int64
+ var n1USN int
+ var n1Public, n1Dirty, n1Deleted bool
+ database.MustScan(t, "scanning n1", db.QueryRow("SELECT book_uuid, body, added_on, edited_on, usn, public, dirty, deleted FROM notes WHERE uuid = ?", n1UUID), &n1BookUUID, &n1Body, &n1AddedOn, &n1EditedOn, &n1USN, &n1Public, &n1Dirty, &n1Deleted)
+
+ var n2BookUUID, n2Body string
+ var n2AddedOn, n2EditedOn int64
+ var n2USN int
+ var n2Public, n2Dirty, n2Deleted bool
+ database.MustScan(t, "scanning n2", db.QueryRow("SELECT book_uuid, body, added_on, edited_on, usn, public, dirty, deleted FROM notes WHERE uuid = ?", n2UUID), &n2BookUUID, &n2Body, &n2AddedOn, &n2EditedOn, &n2USN, &n2Public, &n2Dirty, &n2Deleted)
+
+ assert.Equal(t, n1BookUUID, b1UUID, "n1 BookUUID mismatch")
+ assert.Equal(t, n1Body, "n1 Body", "n1 Body mismatch")
+ assert.Equal(t, n1AddedOn, int64(1), "n1 AddedOn mismatch")
+ assert.Equal(t, n1EditedOn, int64(2), "n1 EditedOn mismatch")
+ assert.Equal(t, n1USN, 20, "n1 USN mismatch")
+ assert.Equal(t, n1Public, true, "n1 Public mismatch")
+ assert.Equal(t, n1Dirty, true, "n1 Dirty mismatch")
+ assert.Equal(t, n1Deleted, false, "n1 Deleted mismatch")
+
+ assert.Equal(t, n2BookUUID, b1UUID, "n2 BookUUID mismatch")
+ assert.Equal(t, n2Body, "", "n2 Body mismatch")
+ assert.Equal(t, n2AddedOn, int64(3), "n2 AddedOn mismatch")
+ assert.Equal(t, n2EditedOn, int64(4), "n2 EditedOn mismatch")
+ assert.Equal(t, n2USN, 21, "n2 USN mismatch")
+ assert.Equal(t, n2Public, false, "n2 Public mismatch")
+ assert.Equal(t, n2Dirty, true, "n2 Dirty mismatch")
+ assert.Equal(t, n2Deleted, true, "n2 Deleted mismatch")
+}
+
+func TestLocalMigration9(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-9-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ b1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "b1")
+
+ n1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting n1", db, `INSERT INTO notes
+ (uuid, book_uuid, body, added_on, edited_on, public, dirty, usn, deleted) VALUES
+ (?, ?, ?, ?, ?, ?, ?, ?, ?)`, n1UUID, b1UUID, "n1 Body", 1, 2, true, true, 20, false)
+ n2UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting n2", db, `INSERT INTO notes
+ (uuid, book_uuid, body, added_on, edited_on, public, dirty, usn, deleted) VALUES
+ (?, ?, ?, ?, ?, ?, ?, ?, ?)`, n2UUID, b1UUID, "n2 Body", 3, 4, false, true, 21, false)
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm9.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+
+ // assert that note_fts was populated with correct values
+ var noteFtsCount int
+ database.MustScan(t, "counting note_fts", db.QueryRow("SELECT count(*) FROM note_fts;"), ¬eFtsCount)
+ assert.Equal(t, noteFtsCount, 2, "noteFtsCount mismatch")
+
+ var resCount int
+ database.MustScan(t, "counting result", db.QueryRow("SELECT count(*) FROM note_fts WHERE note_fts MATCH ?", "n1"), &resCount)
+ assert.Equal(t, resCount, 1, "noteFtsCount mismatch")
+}
+
+func TestLocalMigration10(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-10-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ b1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "123")
+ b2UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 2", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "123 javascript")
+ b3UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 3", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b3UUID, "foo")
+ b4UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 4", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b4UUID, "+123")
+ b5UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 5", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b5UUID, "0123")
+ b6UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 6", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b6UUID, "javascript 123")
+ b7UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 7", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b7UUID, "123 (1)")
+ b8UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 8", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b8UUID, "5")
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm10.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+
+ // assert that note_fts was populated with correct values
+ var b1Label, b2Label, b3Label, b4Label, b5Label, b6Label, b7Label, b8Label string
+ var b1Dirty, b2Dirty, b3Dirty, b4Dirty, b5Dirty, b6Dirty, b7Dirty, b8Dirty bool
+
+ database.MustScan(t, "getting b1", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b1UUID), &b1Label, &b1Dirty)
+ database.MustScan(t, "getting b2", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b2UUID), &b2Label, &b2Dirty)
+ database.MustScan(t, "getting b3", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b3UUID), &b3Label, &b3Dirty)
+ database.MustScan(t, "getting b4", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b4UUID), &b4Label, &b4Dirty)
+ database.MustScan(t, "getting b5", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b5UUID), &b5Label, &b5Dirty)
+ database.MustScan(t, "getting b6", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b6UUID), &b6Label, &b6Dirty)
+ database.MustScan(t, "getting b7", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b7UUID), &b7Label, &b7Dirty)
+ database.MustScan(t, "getting b8", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b8UUID), &b8Label, &b8Dirty)
+
+ assert.Equal(t, b1Label, "123 (2)", "b1Label mismatch")
+ assert.Equal(t, b1Dirty, true, "b1Dirty mismatch")
+ assert.Equal(t, b2Label, "123 javascript", "b2Label mismatch")
+ assert.Equal(t, b2Dirty, false, "b2Dirty mismatch")
+ assert.Equal(t, b3Label, "foo", "b3Label mismatch")
+ assert.Equal(t, b3Dirty, false, "b3Dirty mismatch")
+ assert.Equal(t, b4Label, "+123", "b4Label mismatch")
+ assert.Equal(t, b4Dirty, false, "b4Dirty mismatch")
+ assert.Equal(t, b5Label, "0123 (1)", "b5Label mismatch")
+ assert.Equal(t, b5Dirty, true, "b5Dirty mismatch")
+ assert.Equal(t, b6Label, "javascript 123", "b6Label mismatch")
+ assert.Equal(t, b6Dirty, false, "b6Dirty mismatch")
+ assert.Equal(t, b7Label, "123 (1)", "b7Label mismatch")
+ assert.Equal(t, b7Dirty, false, "b7Dirty mismatch")
+ assert.Equal(t, b8Label, "5 (1)", "b8Label mismatch")
+ assert.Equal(t, b8Dirty, true, "b8Dirty mismatch")
+}
+
+func TestLocalMigration11(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/local-11-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+
+ db := ctx.DB
+
+ b1UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "foo")
+ b2UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 2", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "bar baz")
+ b3UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 3", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b3UUID, "quz qux")
+ b4UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 4", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b4UUID, "quz_qux")
+ b5UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 5", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b5UUID, "foo bar baz quz 123")
+ b6UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 6", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b6UUID, "foo_bar baz")
+ b7UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 7", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b7UUID, "cool ideas")
+ b8UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 8", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b8UUID, "cool_ideas")
+ b9UUID := utils.GenerateUUID()
+ database.MustExec(t, "inserting book 9", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b9UUID, "cool_ideas_2")
+
+ // Execute
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = lm11.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // Test
+ var bookCount int
+ database.MustScan(t, "counting books", db.QueryRow("SELECT count(*) FROM books"), &bookCount)
+ assert.Equal(t, bookCount, 9, "bookCount mismatch")
+
+ // assert that note_fts was populated with correct values
+ var b1Label, b2Label, b3Label, b4Label, b5Label, b6Label, b7Label, b8Label, b9Label string
+ var b1Dirty, b2Dirty, b3Dirty, b4Dirty, b5Dirty, b6Dirty, b7Dirty, b8Dirty, b9Dirty bool
+
+ database.MustScan(t, "getting b1", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b1UUID), &b1Label, &b1Dirty)
+ database.MustScan(t, "getting b2", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b2UUID), &b2Label, &b2Dirty)
+ database.MustScan(t, "getting b3", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b3UUID), &b3Label, &b3Dirty)
+ database.MustScan(t, "getting b4", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b4UUID), &b4Label, &b4Dirty)
+ database.MustScan(t, "getting b5", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b5UUID), &b5Label, &b5Dirty)
+ database.MustScan(t, "getting b6", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b6UUID), &b6Label, &b6Dirty)
+ database.MustScan(t, "getting b7", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b7UUID), &b7Label, &b7Dirty)
+ database.MustScan(t, "getting b8", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b8UUID), &b8Label, &b8Dirty)
+ database.MustScan(t, "getting b9", db.QueryRow("SELECT label, dirty FROM books WHERE uuid = ?", b9UUID), &b9Label, &b9Dirty)
+
+ assert.Equal(t, b1Label, "foo", "b1Label mismatch")
+ assert.Equal(t, b1Dirty, false, "b1Dirty mismatch")
+ assert.Equal(t, b2Label, "bar_baz", "b2Label mismatch")
+ assert.Equal(t, b2Dirty, true, "b2Dirty mismatch")
+ assert.Equal(t, b3Label, "quz_qux_2", "b3Label mismatch")
+ assert.Equal(t, b3Dirty, true, "b3Dirty mismatch")
+ assert.Equal(t, b4Label, "quz_qux", "b4Label mismatch")
+ assert.Equal(t, b4Dirty, false, "b4Dirty mismatch")
+ assert.Equal(t, b5Label, "foo_bar_baz_quz_123", "b5Label mismatch")
+ assert.Equal(t, b5Dirty, true, "b5Dirty mismatch")
+ assert.Equal(t, b6Label, "foo_bar_baz", "b6Label mismatch")
+ assert.Equal(t, b6Dirty, true, "b6Dirty mismatch")
+ assert.Equal(t, b7Label, "cool_ideas_3", "b7Label mismatch")
+ assert.Equal(t, b7Dirty, true, "b7Dirty mismatch")
+ assert.Equal(t, b8Label, "cool_ideas", "b8Label mismatch")
+ assert.Equal(t, b8Dirty, false, "b8Dirty mismatch")
+ assert.Equal(t, b9Label, "cool_ideas_2", "b9Label mismatch")
+ assert.Equal(t, b9Dirty, false, "b9Dirty mismatch")
+}
+
+func TestRemoteMigration1(t *testing.T) {
+ // set up
+ opts := database.TestDBOptions{SchemaSQLPath: "./fixtures/remote-1-pre-schema.sql", SkipMigration: true}
+ ctx := context.InitTestCtx(t, "../tmp", &opts)
+ defer context.TeardownTestCtx(t, ctx)
+ testutils.Login(t, &ctx)
+
+ JSBookUUID := "existing-js-book-uuid"
+ CSSBookUUID := "existing-css-book-uuid"
+ linuxBookUUID := "existing-linux-book-uuid"
+ newJSBookUUID := "new-js-book-uuid"
+ newCSSBookUUID := "new-css-book-uuid"
+
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if r.URL.String() == "/v1/books" {
+ res := []struct {
+ UUID string `json:"uuid"`
+ Label string `json:"label"`
+ }{
+ {
+ UUID: newJSBookUUID,
+ Label: "js",
+ },
+ {
+ UUID: newCSSBookUUID,
+ Label: "css",
+ },
+ // book that only exists on the server. client must ignore.
+ {
+ UUID: "golang-book-uuid",
+ Label: "golang",
+ },
+ }
+
+ if err := json.NewEncoder(w).Encode(res); err != nil {
+ t.Fatal(errors.Wrap(err, "encoding response"))
+ }
+ }
+ }))
+ defer server.Close()
+
+ ctx.APIEndpoint = server.URL
+
+ db := ctx.DB
+ database.MustExec(t, "inserting js book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", JSBookUUID, "js")
+ database.MustExec(t, "inserting css book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", CSSBookUUID, "css")
+ database.MustExec(t, "inserting linux book", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", linuxBookUUID, "linux")
+ database.MustExec(t, "inserting sessionKey", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemSessionKey, "someSessionKey")
+ database.MustExec(t, "inserting sessionKeyExpiry", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemSessionKeyExpiry, time.Now().Add(24*time.Hour).Unix())
+
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "beginning a transaction"))
+ }
+
+ err = rm1.run(ctx, tx)
+ if err != nil {
+ tx.Rollback()
+ t.Fatal(errors.Wrap(err, "failed to run"))
+ }
+
+ tx.Commit()
+
+ // test
+ var postJSBookUUID, postCSSBookUUID, postLinuxBookUUID string
+ database.MustScan(t, "getting js book uuid", db.QueryRow("SELECT uuid FROM books WHERE label = ?", "js"), &postJSBookUUID)
+ database.MustScan(t, "getting css book uuid", db.QueryRow("SELECT uuid FROM books WHERE label = ?", "css"), &postCSSBookUUID)
+ database.MustScan(t, "getting linux book uuid", db.QueryRow("SELECT uuid FROM books WHERE label = ?", "linux"), &postLinuxBookUUID)
+
+ assert.Equal(t, postJSBookUUID, newJSBookUUID, "js book uuid was not updated correctly")
+ assert.Equal(t, postCSSBookUUID, newCSSBookUUID, "css book uuid was not updated correctly")
+ assert.Equal(t, postLinuxBookUUID, linuxBookUUID, "linux book uuid changed")
+}
diff --git a/cli/migrate/migrations.go b/pkg/cli/migrate/migrations.go
similarity index 94%
rename from cli/migrate/migrations.go
rename to pkg/cli/migrate/migrations.go
index 3f6ad00d..e4392b00 100644
--- a/cli/migrate/migrations.go
+++ b/pkg/cli/migrate/migrations.go
@@ -26,20 +26,21 @@ import (
"strings"
"github.com/dnote/actions"
- "github.com/dnote/dnote/cli/client"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
+ "github.com/dnote/dnote/pkg/cli/client"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/log"
"github.com/pkg/errors"
)
type migration struct {
name string
- run func(ctx infra.DnoteCtx, tx *infra.DB) error
+ run func(ctx context.DnoteCtx, tx *database.DB) error
}
var lm1 = migration{
name: "upgrade-edit-note-from-v1-to-v3",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
rows, err := tx.Query("SELECT uuid, data FROM actions WHERE type = ? AND schema = ?", "edit_note", 1)
if err != nil {
return errors.Wrap(err, "querying rows")
@@ -87,7 +88,7 @@ var lm1 = migration{
var lm2 = migration{
name: "upgrade-edit-note-from-v2-to-v3",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
rows, err := tx.Query("SELECT uuid, data FROM actions WHERE type = ? AND schema = ?", "edit_note", 2)
if err != nil {
return errors.Wrap(err, "querying rows")
@@ -132,7 +133,7 @@ var lm2 = migration{
var lm3 = migration{
name: "upgrade-remove-note-from-v1-to-v2",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
rows, err := tx.Query("SELECT uuid, data FROM actions WHERE type = ? AND schema = ?", "remove_note", 1)
if err != nil {
return errors.Wrap(err, "querying rows")
@@ -174,7 +175,7 @@ var lm3 = migration{
var lm4 = migration{
name: "add-dirty-usn-deleted-to-notes-and-books",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
_, err := tx.Exec("ALTER TABLE books ADD COLUMN dirty bool DEFAULT false")
if err != nil {
return errors.Wrap(err, "adding dirty column to books")
@@ -211,7 +212,7 @@ var lm4 = migration{
var lm5 = migration{
name: "mark-action-targets-dirty",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
rows, err := tx.Query("SELECT uuid, data, type FROM actions")
if err != nil {
return errors.Wrap(err, "querying rows")
@@ -273,7 +274,7 @@ var lm5 = migration{
var lm6 = migration{
name: "drop-actions",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
_, err := tx.Exec("DROP TABLE actions;")
if err != nil {
return errors.Wrap(err, "dropping the actions table")
@@ -285,7 +286,7 @@ var lm6 = migration{
var lm7 = migration{
name: "resolve-conflicts-with-reserved-book-names",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
migrateBook := func(name string) error {
var uuid string
@@ -332,7 +333,7 @@ var lm7 = migration{
var lm8 = migration{
name: "drop-note-id-and-rename-content-to-body",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
_, err := tx.Exec(`CREATE TABLE notes_tmp
(
uuid text NOT NULL,
@@ -371,7 +372,7 @@ var lm8 = migration{
var lm9 = migration{
name: "create-fts-index",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
_, err := tx.Exec(`CREATE VIRTUAL TABLE IF NOT EXISTS note_fts USING fts5(content=notes, body, tokenize="porter unicode61 categories 'L* N* Co Ps Pe'");`)
if err != nil {
return errors.Wrap(err, "creating note_fts")
@@ -407,7 +408,7 @@ var lm9 = migration{
var lm10 = migration{
name: "rename-number-only-book",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
migrateBook := func(label string) error {
var uuid string
@@ -467,7 +468,7 @@ var lm10 = migration{
var lm11 = migration{
name: "rename-book-labels-with-space",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
processLabel := func(label string) (string, error) {
sanitized := strings.Replace(label, " ", "_", -1)
@@ -531,7 +532,7 @@ var lm11 = migration{
var rm1 = migration{
name: "sync-book-uuids-from-server",
- run: func(ctx infra.DnoteCtx, tx *infra.DB) error {
+ run: func(ctx context.DnoteCtx, tx *database.DB) error {
sessionKey := ctx.SessionKey
if sessionKey == "" {
return errors.New("not logged in")
diff --git a/cli/core/output.go b/pkg/cli/output/output.go
similarity index 82%
rename from cli/core/output.go
rename to pkg/cli/output/output.go
index 092a0218..d2248523 100644
--- a/cli/core/output.go
+++ b/pkg/cli/output/output.go
@@ -16,17 +16,20 @@
* along with Dnote CLI. If not, see .
*/
-package core
+// Package output provides functions to print informations on the terminal
+// in a consistent manner
+package output
import (
"fmt"
"time"
- "github.com/dnote/dnote/cli/log"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/log"
)
-// PrintNoteInfo prints a note information
-func PrintNoteInfo(info NoteInfo) {
+// NoteInfo prints a note information
+func NoteInfo(info database.NoteInfo) {
log.Infof("book name: %s\n", info.BookLabel)
log.Infof("created at: %s\n", time.Unix(0, info.AddedOn).Format("Jan 2, 2006 3:04pm (MST)"))
if info.EditedOn != 0 {
diff --git a/cli/scripts/build.sh b/pkg/cli/scripts/build.sh
similarity index 97%
rename from cli/scripts/build.sh
rename to pkg/cli/scripts/build.sh
index bb2423af..6fdbb2f1 100755
--- a/cli/scripts/build.sh
+++ b/pkg/cli/scripts/build.sh
@@ -9,7 +9,7 @@ set -eu
version="$1"
projectDir="$GOPATH/src/github.com/dnote/dnote"
-basedir="$GOPATH/src/github.com/dnote/dnote/cli"
+basedir="$GOPATH/src/github.com/dnote/dnote/pkg/cli"
TMP="$basedir/build"
command_exists () {
diff --git a/cli/scripts/dev.sh b/pkg/cli/scripts/dev.sh
similarity index 81%
rename from cli/scripts/dev.sh
rename to pkg/cli/scripts/dev.sh
index 96bd040b..ebe2419d 100755
--- a/cli/scripts/dev.sh
+++ b/pkg/cli/scripts/dev.sh
@@ -6,6 +6,6 @@ set -eux
sudo rm -rf "$(which dnote)" "$GOPATH/bin/cli"
# change tags to darwin if on macos
-go install -ldflags "-X main.apiEndpoint=http://127.0.0.1:5000" --tags "linux fts5" "$GOPATH/src/github.com/dnote/dnote/cli/."
+go install -ldflags "-X main.apiEndpoint=http://127.0.0.1:5000" --tags "linux fts5" "$GOPATH/src/github.com/dnote/dnote/pkg/cli/."
sudo ln -s "$GOPATH/bin/cli" /usr/local/bin/dnote
diff --git a/cli/scripts/dump_schema.sh b/pkg/cli/scripts/dump_schema.sh
similarity index 100%
rename from cli/scripts/dump_schema.sh
rename to pkg/cli/scripts/dump_schema.sh
diff --git a/cli/scripts/release.sh b/pkg/cli/scripts/release.sh
similarity index 100%
rename from cli/scripts/release.sh
rename to pkg/cli/scripts/release.sh
diff --git a/cli/scripts/test.sh b/pkg/cli/scripts/test.sh
similarity index 85%
rename from cli/scripts/test.sh
rename to pkg/cli/scripts/test.sh
index 1af25c1b..9320733b 100755
--- a/cli/scripts/test.sh
+++ b/pkg/cli/scripts/test.sh
@@ -4,7 +4,7 @@
set -eux
-basePath="$GOPATH/src/github.com/dnote/dnote/cli"
+basePath="$GOPATH/src/github.com/dnote/dnote/pkg/cli"
# clear tmp dir in case not properly torn down
rm -rf "$basePath/tmp"
diff --git a/pkg/cli/testutils/main.go b/pkg/cli/testutils/main.go
new file mode 100644
index 00000000..5bf9f4c1
--- /dev/null
+++ b/pkg/cli/testutils/main.go
@@ -0,0 +1,228 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+// Package testutils provides utilities used in tests
+package testutils
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/database"
+ "github.com/dnote/dnote/pkg/cli/utils"
+ "github.com/pkg/errors"
+)
+
+// Login simulates a logged in user by inserting credentials in the local database
+func Login(t *testing.T, ctx *context.DnoteCtx) {
+ db := ctx.DB
+
+ database.MustExec(t, "inserting sessionKey", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemSessionKey, "someSessionKey")
+ database.MustExec(t, "inserting sessionKeyExpiry", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemSessionKeyExpiry, time.Now().Add(24*time.Hour).Unix())
+ database.MustExec(t, "inserting cipherKey", db, "INSERT INTO system (key, value) VALUES (?, ?)", consts.SystemCipherKey, "QUVTMjU2S2V5LTMyQ2hhcmFjdGVyczEyMzQ1Njc4OTA=")
+
+ ctx.SessionKey = "someSessionKey"
+ ctx.SessionKeyExpiry = time.Now().Add(24 * time.Hour).Unix()
+ ctx.CipherKey = []byte("AES256Key-32Characters1234567890")
+}
+
+// RemoveDir cleans up the test env represented by the given context
+func RemoveDir(t *testing.T, dir string) {
+ if err := os.RemoveAll(dir); err != nil {
+ t.Fatal(errors.Wrap(err, "removing the directory"))
+ }
+}
+
+// CopyFixture writes the content of the given fixture to the filename inside the dnote dir
+func CopyFixture(t *testing.T, ctx context.DnoteCtx, fixturePath string, filename string) {
+ fp, err := filepath.Abs(fixturePath)
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "getting the absolute path for fixture"))
+ }
+
+ dp, err := filepath.Abs(filepath.Join(ctx.DnoteDir, filename))
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "getting the absolute path dnote dir"))
+ }
+
+ err = utils.CopyFile(fp, dp)
+ if err != nil {
+ t.Fatal(errors.Wrap(err, "copying the file"))
+ }
+}
+
+// WriteFile writes a file with the given content and filename inside the dnote dir
+func WriteFile(ctx context.DnoteCtx, content []byte, filename string) {
+ dp, err := filepath.Abs(filepath.Join(ctx.DnoteDir, filename))
+ if err != nil {
+ panic(err)
+ }
+
+ if err := ioutil.WriteFile(dp, content, 0644); err != nil {
+ panic(err)
+ }
+}
+
+// ReadFile reads the content of the file with the given name in dnote dir
+func ReadFile(ctx context.DnoteCtx, filename string) []byte {
+ path := filepath.Join(ctx.DnoteDir, filename)
+
+ b, err := ioutil.ReadFile(path)
+ if err != nil {
+ panic(err)
+ }
+
+ return b
+}
+
+// ReadJSON reads JSON fixture to the struct at the destination address
+func ReadJSON(path string, destination interface{}) {
+ var dat []byte
+ dat, err := ioutil.ReadFile(path)
+ if err != nil {
+ panic(errors.Wrap(err, "Failed to load fixture payload"))
+ }
+ if err := json.Unmarshal(dat, destination); err != nil {
+ panic(errors.Wrap(err, "Failed to get event"))
+ }
+}
+
+// NewDnoteCmd returns a new Dnote command and a pointer to stderr
+func NewDnoteCmd(opts RunDnoteCmdOptions, binaryName string, arg ...string) (*exec.Cmd, *bytes.Buffer, *bytes.Buffer, error) {
+ var stderr, stdout bytes.Buffer
+
+ binaryPath, err := filepath.Abs(binaryName)
+ if err != nil {
+ return &exec.Cmd{}, &stderr, &stdout, errors.Wrap(err, "getting the absolute path to the test binary")
+ }
+
+ cmd := exec.Command(binaryPath, arg...)
+ cmd.Env = []string{fmt.Sprintf("DNOTE_DIR=%s", opts.DnoteDir), fmt.Sprintf("DNOTE_HOME_DIR=%s", opts.HomeDir)}
+ cmd.Stderr = &stderr
+ cmd.Stdout = &stdout
+
+ return cmd, &stderr, &stdout, nil
+}
+
+// RunDnoteCmdOptions is an option for RunDnoteCmd
+type RunDnoteCmdOptions struct {
+ DnoteDir string
+ HomeDir string
+}
+
+// RunDnoteCmd runs a dnote command
+func RunDnoteCmd(t *testing.T, opts RunDnoteCmdOptions, binaryName string, arg ...string) {
+ t.Logf("running: %s %s", binaryName, strings.Join(arg, " "))
+
+ cmd, stderr, stdout, err := NewDnoteCmd(opts, binaryName, arg...)
+ if err != nil {
+ t.Logf("\n%s", stdout)
+ t.Fatal(errors.Wrap(err, "getting command").Error())
+ }
+
+ cmd.Env = append(cmd.Env, "DNOTE_DEBUG=1")
+
+ if err := cmd.Run(); err != nil {
+ t.Logf("\n%s", stdout)
+ t.Fatal(errors.Wrapf(err, "running command %s", stderr.String()))
+ }
+
+ // Print stdout if and only if test fails later
+ t.Logf("\n%s", stdout)
+}
+
+// WaitDnoteCmd runs a dnote command and waits until the command is exited
+func WaitDnoteCmd(t *testing.T, opts RunDnoteCmdOptions, runFunc func(io.WriteCloser) error, binaryName string, arg ...string) {
+ t.Logf("running: %s %s", binaryName, strings.Join(arg, " "))
+
+ cmd, stderr, stdout, err := NewDnoteCmd(opts, binaryName, arg...)
+ if err != nil {
+ t.Logf("\n%s", stdout)
+ t.Fatal(errors.Wrap(err, "getting command").Error())
+ }
+
+ stdin, err := cmd.StdinPipe()
+ if err != nil {
+ t.Logf("\n%s", stdout)
+ t.Fatal(errors.Wrap(err, "getting stdin %s"))
+ }
+ defer stdin.Close()
+
+ // Start the program
+ err = cmd.Start()
+ if err != nil {
+ t.Logf("\n%s", stdout)
+ t.Fatal(errors.Wrap(err, "starting command"))
+ }
+
+ err = runFunc(stdin)
+ if err != nil {
+ t.Logf("\n%s", stdout)
+ t.Fatal(errors.Wrap(err, "running with stdin"))
+ }
+
+ err = cmd.Wait()
+ if err != nil {
+ t.Logf("\n%s", stdout)
+ t.Fatal(errors.Wrapf(err, "running command %s", stderr.String()))
+ }
+
+ // Print stdout if and only if test fails later
+ t.Logf("\n%s", stdout)
+}
+
+// UserConfirm simulates confirmation from the user by writing to stdin
+func UserConfirm(stdin io.WriteCloser) error {
+ // confirm
+ if _, err := io.WriteString(stdin, "y\n"); err != nil {
+ return errors.Wrap(err, "indicating confirmation in stdin")
+ }
+
+ return nil
+}
+
+// MustMarshalJSON marshalls the given interface into JSON.
+// If there is any error, it fails the test.
+func MustMarshalJSON(t *testing.T, v interface{}) []byte {
+ b, err := json.Marshal(v)
+ if err != nil {
+ t.Fatalf("%s: marshalling data", t.Name())
+ }
+
+ return b
+}
+
+// MustUnmarshalJSON marshalls the given interface into JSON.
+// If there is any error, it fails the test.
+func MustUnmarshalJSON(t *testing.T, data []byte, v interface{}) {
+ err := json.Unmarshal(data, v)
+ if err != nil {
+ t.Fatalf("%s: unmarshalling data", t.Name())
+ }
+}
diff --git a/pkg/cli/testutils/setup.go b/pkg/cli/testutils/setup.go
new file mode 100644
index 00000000..6b62ecc0
--- /dev/null
+++ b/pkg/cli/testutils/setup.go
@@ -0,0 +1,71 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+package testutils
+
+import (
+ "testing"
+
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/database"
+)
+
+// Setup1 sets up a dnote env #1
+func Setup1(t *testing.T, ctx context.DnoteCtx) {
+ db := ctx.DB
+
+ b1UUID := "js-book-uuid"
+ b2UUID := "linux-book-uuid"
+
+ database.MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "js")
+ database.MustExec(t, "setting up book 2", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b2UUID, "linux")
+
+ database.MustExec(t, "setting up note 1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?)", "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
+}
+
+// Setup2 sets up a dnote env #2
+func Setup2(t *testing.T, db *database.DB) {
+ b1UUID := "js-book-uuid"
+ b2UUID := "linux-book-uuid"
+
+ database.MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label, usn) VALUES (?, ?, ?)", b1UUID, "js", 111)
+ database.MustExec(t, "setting up book 2", db, "INSERT INTO books (uuid, label, usn) VALUES (?, ?, ?)", b2UUID, "linux", 122)
+
+ database.MustExec(t, "setting up note 1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn) VALUES (?, ?, ?, ?, ?)", "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", b1UUID, "n1 body", 1515199951, 11)
+ database.MustExec(t, "setting up note 2", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn) VALUES (?, ?, ?, ?, ?)", "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "n2 body", 1515199943, 12)
+ database.MustExec(t, "setting up note 3", db, "INSERT INTO notes (uuid, book_uuid, body, added_on, usn) VALUES (?, ?, ?, ?, ?)", "3e065d55-6d47-42f2-a6bf-f5844130b2d2", b2UUID, "n3 body", 1515199961, 13)
+}
+
+// Setup3 sets up a dnote env #3
+func Setup3(t *testing.T, db *database.DB) {
+ b1UUID := "js-book-uuid"
+
+ database.MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "js")
+
+ database.MustExec(t, "setting up note 1", db, "INSERT INTO notes (uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?)", "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
+}
+
+// Setup4 sets up a dnote env #4
+func Setup4(t *testing.T, db *database.DB) {
+ b1UUID := "js-book-uuid"
+
+ database.MustExec(t, "setting up book 1", db, "INSERT INTO books (uuid, label) VALUES (?, ?)", b1UUID, "js")
+
+ database.MustExec(t, "setting up note 1", db, "INSERT INTO notes (rowid, uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?, ?)", 1, "43827b9a-c2b0-4c06-a290-97991c896653", b1UUID, "Booleans have toString()", 1515199943)
+ database.MustExec(t, "setting up note 2", db, "INSERT INTO notes (rowid, uuid, book_uuid, body, added_on) VALUES (?, ?, ?, ?, ?)", 2, "f0d0fbb7-31ff-45ae-9f0f-4e429c0c797f", b1UUID, "Date object implements mathematical comparisons", 1515199951)
+}
diff --git a/pkg/cli/ui/editor.go b/pkg/cli/ui/editor.go
new file mode 100644
index 00000000..5ebdb195
--- /dev/null
+++ b/pkg/cli/ui/editor.go
@@ -0,0 +1,146 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+// Package ui provides the user interface for the program
+package ui
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "strings"
+
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/infra"
+ "github.com/dnote/dnote/pkg/cli/utils"
+ "github.com/pkg/errors"
+)
+
+// GetTmpContentPath returns the path to the temporary file containing
+// content being added or edited
+func GetTmpContentPath(ctx context.DnoteCtx) string {
+ return fmt.Sprintf("%s/%s", ctx.DnoteDir, consts.TmpContentFilename)
+}
+
+// getEditorCommand returns the system's editor command with appropriate flags,
+// if necessary, to make the command wait until editor is close to exit.
+func getEditorCommand() string {
+ editor := os.Getenv("EDITOR")
+
+ var ret string
+
+ switch editor {
+ case "atom":
+ ret = "atom -w"
+ case "subl":
+ ret = "subl -n -w"
+ case "mate":
+ ret = "mate -w"
+ case "vim":
+ ret = "vim"
+ case "nano":
+ ret = "nano"
+ case "emacs":
+ ret = "emacs"
+ case "nvim":
+ ret = "nvim"
+ default:
+ ret = "vi"
+ }
+
+ return ret
+}
+
+// SanitizeContent sanitizes note content
+func SanitizeContent(s string) string {
+ var ret string
+
+ ret = strings.Trim(s, " ")
+
+ // Remove newline at the end of the file because POSIX defines a line as
+ // characters followed by a newline
+ ret = strings.TrimSuffix(ret, "\n")
+ ret = strings.TrimSuffix(ret, "\r\n")
+
+ return ret
+}
+
+func newEditorCmd(ctx context.DnoteCtx, fpath string) (*exec.Cmd, error) {
+ config, err := infra.ReadConfig(ctx)
+ if err != nil {
+ return nil, errors.Wrap(err, "reading config")
+ }
+
+ args := strings.Fields(config.Editor)
+ args = append(args, fpath)
+
+ return exec.Command(args[0], args[1:]...), nil
+}
+
+// GetEditorInput gets the user input by launching a text editor and waiting for
+// it to exit
+func GetEditorInput(ctx context.DnoteCtx, fpath string, content *string) error {
+ if !utils.FileExists(fpath) {
+ f, err := os.Create(fpath)
+ if err != nil {
+ return errors.Wrap(err, "creating a temporary content file")
+ }
+ err = f.Close()
+ if err != nil {
+ return errors.Wrap(err, "closing the temporary content file")
+ }
+ }
+
+ cmd, err := newEditorCmd(ctx, fpath)
+ if err != nil {
+ return errors.Wrap(err, "creating an editor command")
+ }
+
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+
+ err = cmd.Start()
+ if err != nil {
+ return errors.Wrapf(err, "launching an editor")
+ }
+
+ err = cmd.Wait()
+ if err != nil {
+ return errors.Wrap(err, "waiting for the editor")
+ }
+
+ b, err := ioutil.ReadFile(fpath)
+ if err != nil {
+ return errors.Wrap(err, "reading the temporary content file")
+ }
+
+ err = os.Remove(fpath)
+ if err != nil {
+ return errors.Wrap(err, "removing the temporary content file")
+ }
+
+ raw := string(b)
+ c := SanitizeContent(raw)
+
+ *content = c
+
+ return nil
+}
diff --git a/pkg/cli/ui/terminal.go b/pkg/cli/ui/terminal.go
new file mode 100644
index 00000000..87b1e486
--- /dev/null
+++ b/pkg/cli/ui/terminal.go
@@ -0,0 +1,97 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+package ui
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "strings"
+ "syscall"
+
+ "github.com/dnote/dnote/pkg/cli/log"
+ "github.com/pkg/errors"
+ "golang.org/x/crypto/ssh/terminal"
+)
+
+func readInput() (string, error) {
+ reader := bufio.NewReader(os.Stdin)
+ input, err := reader.ReadString('\n')
+ if err != nil {
+ return "", errors.Wrap(err, "reading stdin")
+ }
+
+ return strings.Trim(input, "\r\n"), nil
+}
+
+// PromptInput prompts the user input and saves the result to the destination
+func PromptInput(message string, dest *string) error {
+ log.Askf(message, false)
+
+ input, err := readInput()
+ if err != nil {
+ return errors.Wrap(err, "getting user input")
+ }
+
+ *dest = input
+
+ return nil
+}
+
+// PromptPassword prompts the user input a password and saves the result to the destination.
+// The input is masked, meaning it is not echoed on the terminal.
+func PromptPassword(message string, dest *string) error {
+ log.Askf(message, true)
+
+ password, err := terminal.ReadPassword(int(syscall.Stdin))
+ if err != nil {
+ return errors.Wrap(err, "getting user input")
+ }
+
+ fmt.Println("")
+
+ *dest = string(password)
+
+ return nil
+}
+
+// Confirm prompts for user input to confirm a choice
+func Confirm(question string, optimistic bool) (bool, error) {
+ var choices string
+ if optimistic {
+ choices = "(Y/n)"
+ } else {
+ choices = "(y/N)"
+ }
+
+ message := fmt.Sprintf("%s %s", question, choices)
+
+ var input string
+ if err := PromptInput(message, &input); err != nil {
+ return false, errors.Wrap(err, "Failed to get user input")
+ }
+
+ confirmed := input == "y"
+
+ if optimistic {
+ confirmed = confirmed || input == ""
+ }
+
+ return confirmed, nil
+}
diff --git a/cli/core/upgrade.go b/pkg/cli/upgrade/upgrade.go
similarity index 71%
rename from cli/core/upgrade.go
rename to pkg/cli/upgrade/upgrade.go
index de3a3bab..d9b3844c 100644
--- a/cli/core/upgrade.go
+++ b/pkg/cli/upgrade/upgrade.go
@@ -16,16 +16,17 @@
* along with Dnote CLI. If not, see .
*/
-package core
+package upgrade
import (
- "context"
+ stdCtx "context"
"fmt"
"time"
- "github.com/dnote/dnote/cli/infra"
- "github.com/dnote/dnote/cli/log"
- "github.com/dnote/dnote/cli/utils"
+ "github.com/dnote/dnote/pkg/cli/consts"
+ "github.com/dnote/dnote/pkg/cli/context"
+ "github.com/dnote/dnote/pkg/cli/log"
+ "github.com/dnote/dnote/pkg/cli/ui"
"github.com/google/go-github/github"
"github.com/pkg/errors"
)
@@ -34,11 +35,11 @@ import (
var upgradeInterval int64 = 86400 * 7 * 3
// shouldCheckUpdate checks if update should be checked
-func shouldCheckUpdate(ctx infra.DnoteCtx) (bool, error) {
+func shouldCheckUpdate(ctx context.DnoteCtx) (bool, error) {
db := ctx.DB
var lastUpgrade int64
- err := db.QueryRow("SELECT value FROM system WHERE key = ?", infra.SystemLastUpgrade).Scan(&lastUpgrade)
+ err := db.QueryRow("SELECT value FROM system WHERE key = ?", consts.SystemLastUpgrade).Scan(&lastUpgrade)
if err != nil {
return false, errors.Wrap(err, "getting last_udpate")
}
@@ -48,11 +49,11 @@ func shouldCheckUpdate(ctx infra.DnoteCtx) (bool, error) {
return now-lastUpgrade > upgradeInterval, nil
}
-func touchLastUpgrade(ctx infra.DnoteCtx) error {
+func touchLastUpgrade(ctx context.DnoteCtx) error {
db := ctx.DB
now := time.Now().Unix()
- _, err := db.Exec("UPDATE system SET value = ? WHERE key = ?", now, infra.SystemLastUpgrade)
+ _, err := db.Exec("UPDATE system SET value = ? WHERE key = ?", now, consts.SystemLastUpgrade)
if err != nil {
return errors.Wrap(err, "updating last_upgrade")
}
@@ -60,32 +61,34 @@ func touchLastUpgrade(ctx infra.DnoteCtx) error {
return nil
}
-func checkVersion(ctx infra.DnoteCtx) error {
+func checkVersion(ctx context.DnoteCtx) error {
log.Infof("current version is %s\n", ctx.Version)
// Fetch the latest version
gh := github.NewClient(nil)
- releases, _, err := gh.Repositories.ListReleases(context.Background(), "dnote", "cli", nil)
+ releases, _, err := gh.Repositories.ListReleases(stdCtx.Background(), "dnote", "cli", nil)
if err != nil {
return errors.Wrap(err, "fetching releases")
}
latest := releases[0]
- latestVersion := (*latest.TagName)[1:]
+
+ // releases are tagged in a form of cli-v1.0.0
+ latestVersion := (*latest.TagName)[5:]
log.Infof("latest version is %s\n", latestVersion)
if latestVersion == ctx.Version {
log.Success("you are up-to-date\n\n")
} else {
- log.Infof("to upgrade, see https://github.com/dnote/dnote/cli/blob/master/README.md\n")
+ log.Infof("to upgrade, see https://github.com/dnote/dnote/pkg/cli/blob/master/README.md\n")
}
return nil
}
-// CheckUpdate triggers update if needed
-func CheckUpdate(ctx infra.DnoteCtx) error {
+// Check triggers update if needed
+func Check(ctx context.DnoteCtx) error {
shouldCheck, err := shouldCheckUpdate(ctx)
if err != nil {
return errors.Wrap(err, "checking if dnote should check update")
@@ -100,7 +103,7 @@ func CheckUpdate(ctx infra.DnoteCtx) error {
}
fmt.Printf("\n")
- willCheck, err := utils.AskConfirmation("check for upgrade?", true)
+ willCheck, err := ui.Confirm("check for upgrade?", true)
if err != nil {
return errors.Wrap(err, "getting user confirmation")
}
diff --git a/cli/utils/diff/diff.go b/pkg/cli/utils/diff/diff.go
similarity index 100%
rename from cli/utils/diff/diff.go
rename to pkg/cli/utils/diff/diff.go
diff --git a/cli/utils/diff/diff_test.go b/pkg/cli/utils/diff/diff_test.go
similarity index 95%
rename from cli/utils/diff/diff_test.go
rename to pkg/cli/utils/diff/diff_test.go
index fca05da4..f784b1e2 100644
--- a/cli/utils/diff/diff_test.go
+++ b/pkg/cli/utils/diff/diff_test.go
@@ -22,7 +22,7 @@ import (
"fmt"
"testing"
- "github.com/dnote/dnote/cli/testutils"
+ "github.com/dnote/dnote/pkg/assert"
"github.com/sergi/go-diff/diffmatchpatch"
)
@@ -143,7 +143,7 @@ func TestDo(t *testing.T) {
result := Do(tc.s1, tc.s2)
t.Run(fmt.Sprintf("test case %d", idx), func(t *testing.T) {
- testutils.AssertDeepEqual(t, result, tc.expected, "result mismatch")
+ assert.DeepEqual(t, result, tc.expected, "result mismatch")
})
}
}
diff --git a/cli/utils/utils.go b/pkg/cli/utils/files.go
similarity index 55%
rename from cli/utils/utils.go
rename to pkg/cli/utils/files.go
index 9a4d4a10..452ee475 100644
--- a/cli/utils/utils.go
+++ b/pkg/cli/utils/files.go
@@ -19,92 +19,28 @@
package utils
import (
- "bufio"
- "fmt"
"io"
"io/ioutil"
- "net/http"
"os"
"path/filepath"
- "regexp"
- "strings"
- "syscall"
- "github.com/dnote/dnote/cli/log"
"github.com/pkg/errors"
- "github.com/satori/go.uuid"
- "golang.org/x/crypto/ssh/terminal"
)
-// GenerateUUID returns a uid
-func GenerateUUID() string {
- return uuid.NewV4().String()
-}
-
-func getInput() (string, error) {
- reader := bufio.NewReader(os.Stdin)
- input, err := reader.ReadString('\n')
+// ReadFileAbs reads the content of the file with the given file path by resolving
+// it as an absolute path
+func ReadFileAbs(relpath string) []byte {
+ fp, err := filepath.Abs(relpath)
if err != nil {
- return "", errors.Wrap(err, "reading stdin")
+ panic(err)
}
- return strings.Trim(input, "\r\n"), nil
-}
-
-// PromptInput prompts the user input and saves the result to the destination
-func PromptInput(message string, dest *string) error {
- log.Askf(message, false)
-
- input, err := getInput()
+ b, err := ioutil.ReadFile(fp)
if err != nil {
- return errors.Wrap(err, "getting user input")
+ panic(err)
}
- *dest = input
-
- return nil
-}
-
-// PromptPassword prompts the user input a password and saves the result to the destination.
-// The input is masked, meaning it is not echoed on the terminal.
-func PromptPassword(message string, dest *string) error {
- log.Askf(message, true)
-
- password, err := terminal.ReadPassword(int(syscall.Stdin))
- if err != nil {
- return errors.Wrap(err, "getting user input")
- }
-
- fmt.Println("")
-
- *dest = string(password)
-
- return nil
-}
-
-// AskConfirmation prompts for user input to confirm a choice
-func AskConfirmation(question string, optimistic bool) (bool, error) {
- var choices string
- if optimistic {
- choices = "(Y/n)"
- } else {
- choices = "(y/N)"
- }
-
- message := fmt.Sprintf("%s %s", question, choices)
-
- var input string
- if err := PromptInput(message, &input); err != nil {
- return false, errors.Wrap(err, "Failed to get user input")
- }
-
- confirmed := input == "y"
-
- if optimistic {
- confirmed = confirmed || input == ""
- }
-
- return confirmed, nil
+ return b
}
// FileExists checks if the file exists at the given path
@@ -160,22 +96,6 @@ func CopyDir(src, dest string) error {
return nil
}
-// checkRespErr checks if the given http response indicates an error. It returns a boolean indicating
-// if the response is an error, and a decoded error message.
-func checkRespErr(res *http.Response) error {
- if res.StatusCode < 400 {
- return nil
- }
-
- body, err := ioutil.ReadAll(res.Body)
- if err != nil {
- return errors.Wrapf(err, "server responded with %d but could not read the response body", res.StatusCode)
- }
-
- bodyStr := string(body)
- return errors.Errorf(`response %d "%s"`, res.StatusCode, strings.TrimRight(bodyStr, "\n"))
-}
-
// CopyFile copies a file from the src to dest
func CopyFile(src, dest string) error {
in, err := os.Open(src)
@@ -213,15 +133,3 @@ func CopyFile(src, dest string) error {
return nil
}
-
-// regexNumber is a regex that matches a string that looks like an integer
-var regexNumber = regexp.MustCompile(`^\d+$`)
-
-// IsNumber checks if the given string is in the form of a number
-func IsNumber(s string) bool {
- if s == "" {
- return false
- }
-
- return regexNumber.MatchString(s)
-}
diff --git a/pkg/cli/utils/utils.go b/pkg/cli/utils/utils.go
new file mode 100644
index 00000000..0321c829
--- /dev/null
+++ b/pkg/cli/utils/utils.go
@@ -0,0 +1,42 @@
+/* Copyright (C) 2019 Monomax Software Pty Ltd
+ *
+ * This file is part of Dnote CLI.
+ *
+ * Dnote CLI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dnote CLI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dnote CLI. If not, see .
+ */
+
+package utils
+
+import (
+ "regexp"
+
+ "github.com/satori/go.uuid"
+)
+
+// GenerateUUID returns a uid
+func GenerateUUID() string {
+ return uuid.NewV4().String()
+}
+
+// regexNumber is a regex that matches a string that looks like an integer
+var regexNumber = regexp.MustCompile(`^\d+$`)
+
+// IsNumber checks if the given string is in the form of a number
+func IsNumber(s string) bool {
+ if s == "" {
+ return false
+ }
+
+ return regexNumber.MatchString(s)
+}
diff --git a/server/.gitignore b/pkg/server/.gitignore
similarity index 100%
rename from server/.gitignore
rename to pkg/server/.gitignore
diff --git a/server/Gopkg.lock b/pkg/server/Gopkg.lock
similarity index 95%
rename from server/Gopkg.lock
rename to pkg/server/Gopkg.lock
index 12db3dda..7c80517d 100644
--- a/server/Gopkg.lock
+++ b/pkg/server/Gopkg.lock
@@ -29,6 +29,14 @@
revision = "c5c95ec357c8235fbd7f34e8c843d36783f3fad9"
version = "v0.2.0"
+[[projects]]
+ branch = "endpoint-186"
+ digest = "1:b56e65cab256427453f4454af3e7be2c1c544b52332772dbf7e6992aa7fdf599"
+ name = "github.com/dnote/dnote"
+ packages = ["pkg/assert"]
+ pruneopts = ""
+ revision = "54646c6bf85fba5efb8b4de67c9fed19cdbe0d97"
+
[[projects]]
digest = "1:529d738b7976c3848cae5cf3a8036440166835e389c1f617af701eeb12a0518d"
name = "github.com/golang/protobuf"
@@ -159,6 +167,7 @@
"customer",
"form",
"paymentsource",
+ "source",
"sub",
"webhook",
]
@@ -247,6 +256,7 @@
analyzer-version = 1
input-imports = [
"github.com/aymerick/douceur/inliner",
+ "github.com/dnote/dnote/pkg/assert",
"github.com/gorilla/mux",
"github.com/gorilla/securecookie",
"github.com/gorilla/sessions",
@@ -264,6 +274,7 @@
"github.com/stripe/stripe-go/card",
"github.com/stripe/stripe-go/customer",
"github.com/stripe/stripe-go/paymentsource",
+ "github.com/stripe/stripe-go/source",
"github.com/stripe/stripe-go/sub",
"github.com/stripe/stripe-go/webhook",
"golang.org/x/crypto/bcrypt",
diff --git a/server/Gopkg.toml b/pkg/server/Gopkg.toml
similarity index 100%
rename from server/Gopkg.toml
rename to pkg/server/Gopkg.toml
diff --git a/server/README.md b/pkg/server/README.md
similarity index 100%
rename from server/README.md
rename to pkg/server/README.md
diff --git a/server/api/.env.dev b/pkg/server/api/.env.dev
similarity index 100%
rename from server/api/.env.dev
rename to pkg/server/api/.env.dev
diff --git a/server/api/.env.test b/pkg/server/api/.env.test
similarity index 95%
rename from server/api/.env.test
rename to pkg/server/api/.env.test
index 976dcecd..9342b643 100644
--- a/server/api/.env.test
+++ b/pkg/server/api/.env.test
@@ -5,7 +5,7 @@ GO_ENV=DEVELOPMENT
DB_HOST=localhost
POSTGRES_DB=dnote_test
-POSTGRES_USER=sung
+POSTGRES_USER=postgres
SmtpUsername=mock-SmtpUsername
SmtpPassword=mock-SmtpPassword
diff --git a/server/api/.gitignore b/pkg/server/api/.gitignore
similarity index 100%
rename from server/api/.gitignore
rename to pkg/server/api/.gitignore
diff --git a/server/api/README.md b/pkg/server/api/README.md
similarity index 100%
rename from server/api/README.md
rename to pkg/server/api/README.md
diff --git a/server/api/clock/clock.go b/pkg/server/api/clock/clock.go
similarity index 100%
rename from server/api/clock/clock.go
rename to pkg/server/api/clock/clock.go
diff --git a/server/api/crypt/crypt.go b/pkg/server/api/crypt/crypt.go
similarity index 100%
rename from server/api/crypt/crypt.go
rename to pkg/server/api/crypt/crypt.go
diff --git a/server/api/handlers/auth.go b/pkg/server/api/handlers/auth.go
similarity index 98%
rename from server/api/handlers/auth.go
rename to pkg/server/api/handlers/auth.go
index 827f54fa..0c34cf6a 100644
--- a/server/api/handlers/auth.go
+++ b/pkg/server/api/handlers/auth.go
@@ -24,9 +24,9 @@ import (
"net/http"
"time"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/api/operations"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/api/operations"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/jinzhu/gorm"
"github.com/markbates/goth"
"github.com/markbates/goth/gothic"
diff --git a/server/api/handlers/digests.go b/pkg/server/api/handlers/digests.go
similarity index 95%
rename from server/api/handlers/digests.go
rename to pkg/server/api/handlers/digests.go
index 4d363f6d..8a12b6ad 100644
--- a/server/api/handlers/digests.go
+++ b/pkg/server/api/handlers/digests.go
@@ -23,10 +23,10 @@ import (
"net/http"
"strconv"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/api/logger"
- "github.com/dnote/dnote/server/api/presenters"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/api/logger"
+ "github.com/dnote/dnote/pkg/server/api/presenters"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/gorilla/mux"
"github.com/pkg/errors"
)
diff --git a/server/api/handlers/health.go b/pkg/server/api/handlers/health.go
similarity index 100%
rename from server/api/handlers/health.go
rename to pkg/server/api/handlers/health.go
diff --git a/server/api/handlers/helpers.go b/pkg/server/api/handlers/helpers.go
similarity index 96%
rename from server/api/handlers/helpers.go
rename to pkg/server/api/handlers/helpers.go
index cc2f26a4..fe3d7021 100644
--- a/server/api/handlers/helpers.go
+++ b/pkg/server/api/handlers/helpers.go
@@ -24,8 +24,8 @@ import (
"net/http"
"strings"
- "github.com/dnote/dnote/server/api/logger"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/logger"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
)
diff --git a/server/api/handlers/limit.go b/pkg/server/api/handlers/limit.go
similarity index 100%
rename from server/api/handlers/limit.go
rename to pkg/server/api/handlers/limit.go
diff --git a/server/api/handlers/notes.go b/pkg/server/api/handlers/notes.go
similarity index 98%
rename from server/api/handlers/notes.go
rename to pkg/server/api/handlers/notes.go
index b9937f7c..6d34f353 100644
--- a/server/api/handlers/notes.go
+++ b/pkg/server/api/handlers/notes.go
@@ -26,9 +26,9 @@ import (
"strings"
"time"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/api/presenters"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/api/presenters"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/gorilla/mux"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
diff --git a/server/api/handlers/routes.go b/pkg/server/api/handlers/routes.go
similarity index 98%
rename from server/api/handlers/routes.go
rename to pkg/server/api/handlers/routes.go
index ebc28ea0..30ac3004 100644
--- a/server/api/handlers/routes.go
+++ b/pkg/server/api/handlers/routes.go
@@ -26,10 +26,10 @@ import (
"strings"
"time"
- "github.com/dnote/dnote/server/api/clock"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/api/logger"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/clock"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/api/logger"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/gorilla/mux"
"github.com/markbates/goth/gothic"
"github.com/pkg/errors"
diff --git a/server/api/handlers/routes_test.go b/pkg/server/api/handlers/routes_test.go
similarity index 90%
rename from server/api/handlers/routes_test.go
rename to pkg/server/api/handlers/routes_test.go
index 4305b970..43ae67dc 100644
--- a/server/api/handlers/routes_test.go
+++ b/pkg/server/api/handlers/routes_test.go
@@ -25,8 +25,9 @@ import (
"testing"
"time"
- "github.com/dnote/dnote/server/database"
- "github.com/dnote/dnote/server/testutils"
+ "github.com/dnote/dnote/pkg/assert"
+ "github.com/dnote/dnote/pkg/server/database"
+ "github.com/dnote/dnote/pkg/server/testutils"
"github.com/pkg/errors"
)
@@ -78,7 +79,7 @@ func TestGetSessionKeyFromCookie(t *testing.T) {
t.Fatal(errors.Wrap(err, "executing"))
}
- testutils.AssertEqual(t, got, tc.expected, "result mismatch")
+ assert.Equal(t, got, tc.expected, "result mismatch")
}
}
@@ -108,7 +109,7 @@ func TestGetSessionKeyFromAuth(t *testing.T) {
t.Fatal(errors.Wrap(err, "executing"))
}
- testutils.AssertEqual(t, got, tc.expected, "result mismatch")
+ assert.Equal(t, got, tc.expected, "result mismatch")
}
}
@@ -178,7 +179,7 @@ func TestGetCredential(t *testing.T) {
t.Fatal(errors.Wrap(err, "executing"))
}
- testutils.AssertEqual(t, got, tc.expected, "result mismatch")
+ assert.Equal(t, got, tc.expected, "result mismatch")
}
}
@@ -234,7 +235,7 @@ func TestAuthMiddleware(t *testing.T) {
res := testutils.HTTPDo(t, req)
// test
- testutils.AssertEqual(t, res.StatusCode, tc.expectedStatus, "status code mismatch")
+ assert.Equal(t, res.StatusCode, tc.expectedStatus, "status code mismatch")
})
}
})
@@ -279,7 +280,7 @@ func TestAuthMiddleware(t *testing.T) {
res := testutils.HTTPDo(t, req)
// test
- testutils.AssertEqual(t, res.StatusCode, tc.expectedStatus, "status code mismatch")
+ assert.Equal(t, res.StatusCode, tc.expectedStatus, "status code mismatch")
})
}
})
@@ -291,7 +292,7 @@ func TestAuthMiddleware(t *testing.T) {
res := testutils.HTTPDo(t, req)
// test
- testutils.AssertEqual(t, res.StatusCode, http.StatusUnauthorized, "status code mismatch")
+ assert.Equal(t, res.StatusCode, http.StatusUnauthorized, "status code mismatch")
})
}
@@ -342,7 +343,7 @@ func TestTokenAuthMiddleWare(t *testing.T) {
res := testutils.HTTPDo(t, req)
// test
- testutils.AssertEqual(t, res.StatusCode, tc.expectedStatus, "status code mismatch")
+ assert.Equal(t, res.StatusCode, tc.expectedStatus, "status code mismatch")
})
}
})
@@ -371,7 +372,7 @@ func TestTokenAuthMiddleWare(t *testing.T) {
res := testutils.HTTPDo(t, req)
// test
- testutils.AssertEqual(t, res.StatusCode, tc.expectedStatus, "status code mismatch")
+ assert.Equal(t, res.StatusCode, tc.expectedStatus, "status code mismatch")
})
}
})
@@ -408,7 +409,7 @@ func TestTokenAuthMiddleWare(t *testing.T) {
res := testutils.HTTPDo(t, req)
// test
- testutils.AssertEqual(t, res.StatusCode, tc.expectedStatus, "status code mismatch")
+ assert.Equal(t, res.StatusCode, tc.expectedStatus, "status code mismatch")
})
}
})
@@ -420,6 +421,6 @@ func TestTokenAuthMiddleWare(t *testing.T) {
res := testutils.HTTPDo(t, req)
// test
- testutils.AssertEqual(t, res.StatusCode, http.StatusUnauthorized, "status code mismatch")
+ assert.Equal(t, res.StatusCode, http.StatusUnauthorized, "status code mismatch")
})
}
diff --git a/server/api/handlers/semver.go b/pkg/server/api/handlers/semver.go
similarity index 100%
rename from server/api/handlers/semver.go
rename to pkg/server/api/handlers/semver.go
diff --git a/server/api/handlers/subscription.go b/pkg/server/api/handlers/subscription.go
similarity index 98%
rename from server/api/handlers/subscription.go
rename to pkg/server/api/handlers/subscription.go
index 5a0614da..d77c19be 100644
--- a/server/api/handlers/subscription.go
+++ b/pkg/server/api/handlers/subscription.go
@@ -26,9 +26,9 @@ import (
"os"
"strings"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/api/operations"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/api/operations"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
"github.com/stripe/stripe-go"
diff --git a/server/api/handlers/user.go b/pkg/server/api/handlers/user.go
similarity index 98%
rename from server/api/handlers/user.go
rename to pkg/server/api/handlers/user.go
index 9c402cf3..8af7e1f3 100644
--- a/server/api/handlers/user.go
+++ b/pkg/server/api/handlers/user.go
@@ -23,11 +23,11 @@ import (
"net/http"
"time"
- "github.com/dnote/dnote/server/api/crypt"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/api/operations"
- "github.com/dnote/dnote/server/database"
- "github.com/dnote/dnote/server/mailer"
+ "github.com/dnote/dnote/pkg/server/api/crypt"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/api/operations"
+ "github.com/dnote/dnote/pkg/server/database"
+ "github.com/dnote/dnote/pkg/server/mailer"
"github.com/pkg/errors"
)
diff --git a/server/api/handlers/v1_auth.go b/pkg/server/api/handlers/v1_auth.go
similarity index 98%
rename from server/api/handlers/v1_auth.go
rename to pkg/server/api/handlers/v1_auth.go
index 62decdf1..659dd695 100644
--- a/server/api/handlers/v1_auth.go
+++ b/pkg/server/api/handlers/v1_auth.go
@@ -25,9 +25,9 @@ import (
"github.com/pkg/errors"
- "github.com/dnote/dnote/server/api/crypt"
- "github.com/dnote/dnote/server/api/operations"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/crypt"
+ "github.com/dnote/dnote/pkg/server/api/operations"
+ "github.com/dnote/dnote/pkg/server/database"
)
// ErrLoginFailure is an error for failed login
diff --git a/server/api/handlers/v1_books.go b/pkg/server/api/handlers/v1_books.go
similarity index 97%
rename from server/api/handlers/v1_books.go
rename to pkg/server/api/handlers/v1_books.go
index b0e638b1..b016e2d4 100644
--- a/server/api/handlers/v1_books.go
+++ b/pkg/server/api/handlers/v1_books.go
@@ -24,10 +24,10 @@ import (
"net/http"
"net/url"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/api/operations"
- "github.com/dnote/dnote/server/api/presenters"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/api/operations"
+ "github.com/dnote/dnote/pkg/server/api/presenters"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/gorilla/mux"
"github.com/pkg/errors"
)
diff --git a/server/api/handlers/v1_notes.go b/pkg/server/api/handlers/v1_notes.go
similarity index 95%
rename from server/api/handlers/v1_notes.go
rename to pkg/server/api/handlers/v1_notes.go
index 03d42732..84d51eba 100644
--- a/server/api/handlers/v1_notes.go
+++ b/pkg/server/api/handlers/v1_notes.go
@@ -22,10 +22,10 @@ import (
"encoding/json"
"net/http"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/api/operations"
- "github.com/dnote/dnote/server/api/presenters"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/api/operations"
+ "github.com/dnote/dnote/pkg/server/api/presenters"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/gorilla/mux"
"github.com/pkg/errors"
)
diff --git a/server/api/handlers/v1_sync.go b/pkg/server/api/handlers/v1_sync.go
similarity index 98%
rename from server/api/handlers/v1_sync.go
rename to pkg/server/api/handlers/v1_sync.go
index b281983c..13e94f54 100644
--- a/server/api/handlers/v1_sync.go
+++ b/pkg/server/api/handlers/v1_sync.go
@@ -27,8 +27,8 @@ import (
"strconv"
"time"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/pkg/errors"
)
diff --git a/server/api/handlers/v1_sync_test.go b/pkg/server/api/handlers/v1_sync_test.go
similarity index 84%
rename from server/api/handlers/v1_sync_test.go
rename to pkg/server/api/handlers/v1_sync_test.go
index 016cba7f..69e20ee6 100644
--- a/server/api/handlers/v1_sync_test.go
+++ b/pkg/server/api/handlers/v1_sync_test.go
@@ -24,7 +24,7 @@ import (
"reflect"
"testing"
- "github.com/dnote/dnote/server/testutils"
+ "github.com/dnote/dnote/pkg/assert"
"github.com/pkg/errors"
)
@@ -85,9 +85,9 @@ func TestParseGetSyncFragmentQuery(t *testing.T) {
afterUSN, limit, err := parseGetSyncFragmentQuery(q)
ok := reflect.DeepEqual(err, tc.err)
- testutils.AssertEqual(t, ok, true, fmt.Sprintf("err mismatch for test case %d. Expected: %+v. Got: %+v", idx, tc.err, err))
+ assert.Equal(t, ok, true, fmt.Sprintf("err mismatch for test case %d. Expected: %+v. Got: %+v", idx, tc.err, err))
- testutils.AssertEqual(t, afterUSN, tc.afterUSN, fmt.Sprintf("afterUSN mismatch for test case %d", idx))
- testutils.AssertEqual(t, limit, tc.limit, fmt.Sprintf("limit mismatch for test case %d", idx))
+ assert.Equal(t, afterUSN, tc.afterUSN, fmt.Sprintf("afterUSN mismatch for test case %d", idx))
+ assert.Equal(t, limit, tc.limit, fmt.Sprintf("limit mismatch for test case %d", idx))
}
}
diff --git a/server/api/handlers/v2_books.go b/pkg/server/api/handlers/v2_books.go
similarity index 93%
rename from server/api/handlers/v2_books.go
rename to pkg/server/api/handlers/v2_books.go
index efce3960..cd77dae1 100644
--- a/server/api/handlers/v2_books.go
+++ b/pkg/server/api/handlers/v2_books.go
@@ -22,10 +22,10 @@ import (
"encoding/json"
"net/http"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/api/operations"
- "github.com/dnote/dnote/server/api/presenters"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/api/operations"
+ "github.com/dnote/dnote/pkg/server/api/presenters"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/pkg/errors"
)
diff --git a/server/api/handlers/v2_notes.go b/pkg/server/api/handlers/v2_notes.go
similarity index 93%
rename from server/api/handlers/v2_notes.go
rename to pkg/server/api/handlers/v2_notes.go
index ae310f5b..85920d98 100644
--- a/server/api/handlers/v2_notes.go
+++ b/pkg/server/api/handlers/v2_notes.go
@@ -22,10 +22,10 @@ import (
"encoding/json"
"net/http"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/api/operations"
- "github.com/dnote/dnote/server/api/presenters"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/api/operations"
+ "github.com/dnote/dnote/pkg/server/api/presenters"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/pkg/errors"
)
diff --git a/server/api/helpers/const.go b/pkg/server/api/helpers/const.go
similarity index 100%
rename from server/api/helpers/const.go
rename to pkg/server/api/helpers/const.go
diff --git a/server/api/helpers/helpers.go b/pkg/server/api/helpers/helpers.go
similarity index 96%
rename from server/api/helpers/helpers.go
rename to pkg/server/api/helpers/helpers.go
index 9289034f..ea14b8a7 100644
--- a/server/api/helpers/helpers.go
+++ b/pkg/server/api/helpers/helpers.go
@@ -19,7 +19,7 @@
package helpers
import (
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/pkg/errors"
"github.com/satori/go.uuid"
)
diff --git a/server/api/logger/main.go b/pkg/server/api/logger/main.go
similarity index 100%
rename from server/api/logger/main.go
rename to pkg/server/api/logger/main.go
diff --git a/server/api/main.go b/pkg/server/api/main.go
similarity index 91%
rename from server/api/main.go
rename to pkg/server/api/main.go
index 2047d3fd..819a326a 100644
--- a/server/api/main.go
+++ b/pkg/server/api/main.go
@@ -25,11 +25,11 @@ import (
"net/http"
"os"
- "github.com/dnote/dnote/server/api/clock"
- "github.com/dnote/dnote/server/api/handlers"
- "github.com/dnote/dnote/server/api/logger"
- "github.com/dnote/dnote/server/database"
- "github.com/dnote/dnote/server/mailer"
+ "github.com/dnote/dnote/pkg/server/api/clock"
+ "github.com/dnote/dnote/pkg/server/api/handlers"
+ "github.com/dnote/dnote/pkg/server/api/logger"
+ "github.com/dnote/dnote/pkg/server/database"
+ "github.com/dnote/dnote/pkg/server/mailer"
"github.com/gorilla/mux"
"github.com/gorilla/securecookie"
diff --git a/server/api/operations/books.go b/pkg/server/api/operations/books.go
similarity index 95%
rename from server/api/operations/books.go
rename to pkg/server/api/operations/books.go
index 5f8b0734..b11721df 100644
--- a/server/api/operations/books.go
+++ b/pkg/server/api/operations/books.go
@@ -19,9 +19,9 @@
package operations
import (
- "github.com/dnote/dnote/server/api/clock"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/clock"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
)
diff --git a/server/api/operations/books_test.go b/pkg/server/api/operations/books_test.go
similarity index 69%
rename from server/api/operations/books_test.go
rename to pkg/server/api/operations/books_test.go
index 9887a98d..005f25d2 100644
--- a/server/api/operations/books_test.go
+++ b/pkg/server/api/operations/books_test.go
@@ -22,9 +22,10 @@ import (
"fmt"
"testing"
- "github.com/dnote/dnote/server/api/clock"
- "github.com/dnote/dnote/server/database"
- "github.com/dnote/dnote/server/testutils"
+ "github.com/dnote/dnote/pkg/assert"
+ "github.com/dnote/dnote/pkg/server/api/clock"
+ "github.com/dnote/dnote/pkg/server/database"
+ "github.com/dnote/dnote/pkg/server/testutils"
"github.com/pkg/errors"
)
@@ -87,16 +88,16 @@ func TestCreateBook(t *testing.T) {
t.Fatal(errors.Wrap(err, "finding user"))
}
- testutils.AssertEqual(t, bookCount, 1, "book count mismatch")
- testutils.AssertEqual(t, bookRecord.UserID, user.ID, "book user_id mismatch")
- testutils.AssertEqual(t, bookRecord.Label, tc.label, "book label mismatch")
- testutils.AssertEqual(t, bookRecord.USN, tc.expectedUSN, "book label mismatch")
+ assert.Equal(t, bookCount, 1, "book count mismatch")
+ assert.Equal(t, bookRecord.UserID, user.ID, "book user_id mismatch")
+ assert.Equal(t, bookRecord.Label, tc.label, "book label mismatch")
+ assert.Equal(t, bookRecord.USN, tc.expectedUSN, "book label mismatch")
- testutils.AssertNotEqual(t, book.UUID, "", "book uuid should have been generated")
- testutils.AssertEqual(t, book.UserID, user.ID, "returned book user_id mismatch")
- testutils.AssertEqual(t, book.Label, tc.label, "returned book label mismatch")
- testutils.AssertEqual(t, book.USN, tc.expectedUSN, "returned book usn mismatch")
- testutils.AssertEqual(t, userRecord.MaxUSN, tc.expectedUSN, "user max_usn mismatch")
+ assert.NotEqual(t, book.UUID, "", "book uuid should have been generated")
+ assert.Equal(t, book.UserID, user.ID, "returned book user_id mismatch")
+ assert.Equal(t, book.Label, tc.label, "returned book label mismatch")
+ assert.Equal(t, book.USN, tc.expectedUSN, "returned book usn mismatch")
+ assert.Equal(t, userRecord.MaxUSN, tc.expectedUSN, "user max_usn mismatch")
}()
}
}
@@ -150,18 +151,18 @@ func TestDeleteBook(t *testing.T) {
testutils.MustExec(t, db.First(&bookRecord), fmt.Sprintf("finding book for test case %d", idx))
testutils.MustExec(t, db.Where("id = ?", user.ID).First(&userRecord), fmt.Sprintf("finding user for test case %d", idx))
- testutils.AssertEqual(t, bookCount, 1, "book count mismatch")
- testutils.AssertEqual(t, bookRecord.UserID, user.ID, "book user_id mismatch")
- testutils.AssertEqual(t, bookRecord.Label, "", "book label mismatch")
- testutils.AssertEqual(t, bookRecord.Deleted, true, "book deleted flag mismatch")
- testutils.AssertEqual(t, bookRecord.USN, tc.expectedUSN, "book label mismatch")
+ assert.Equal(t, bookCount, 1, "book count mismatch")
+ assert.Equal(t, bookRecord.UserID, user.ID, "book user_id mismatch")
+ assert.Equal(t, bookRecord.Label, "", "book label mismatch")
+ assert.Equal(t, bookRecord.Deleted, true, "book deleted flag mismatch")
+ assert.Equal(t, bookRecord.USN, tc.expectedUSN, "book label mismatch")
- testutils.AssertEqual(t, ret.UserID, user.ID, "returned book user_id mismatch")
- testutils.AssertEqual(t, ret.Label, "", "returned book label mismatch")
- testutils.AssertEqual(t, ret.Deleted, true, "returned book deleted flag mismatch")
- testutils.AssertEqual(t, ret.USN, tc.expectedUSN, "returned book label mismatch")
+ assert.Equal(t, ret.UserID, user.ID, "returned book user_id mismatch")
+ assert.Equal(t, ret.Label, "", "returned book label mismatch")
+ assert.Equal(t, ret.Deleted, true, "returned book deleted flag mismatch")
+ assert.Equal(t, ret.USN, tc.expectedUSN, "returned book label mismatch")
- testutils.AssertEqual(t, userRecord.MaxUSN, tc.expectedUSN, "user max_usn mismatch")
+ assert.Equal(t, userRecord.MaxUSN, tc.expectedUSN, "user max_usn mismatch")
}()
}
}
@@ -231,18 +232,18 @@ func TestUpdateBook(t *testing.T) {
testutils.MustExec(t, db.First(&bookRecord), fmt.Sprintf("finding book for test case %d", idx))
testutils.MustExec(t, db.Where("id = ?", user.ID).First(&userRecord), fmt.Sprintf("finding user for test case %d", idx))
- testutils.AssertEqual(t, bookCount, 1, "book count mismatch")
+ assert.Equal(t, bookCount, 1, "book count mismatch")
- testutils.AssertEqual(t, bookRecord.UserID, user.ID, "book user_id mismatch")
- testutils.AssertEqual(t, bookRecord.Label, tc.expectedLabel, "book label mismatch")
- testutils.AssertEqual(t, bookRecord.USN, tc.expectedUSN, "book label mismatch")
- testutils.AssertEqual(t, bookRecord.EditedOn, c.Now().UnixNano(), "book edited_on mismatch")
- testutils.AssertEqual(t, book.UserID, user.ID, "returned book user_id mismatch")
- testutils.AssertEqual(t, book.Label, tc.expectedLabel, "returned book label mismatch")
- testutils.AssertEqual(t, book.USN, tc.expectedUSN, "returned book usn mismatch")
- testutils.AssertEqual(t, book.EditedOn, c.Now().UnixNano(), "returned book edited_on mismatch")
+ assert.Equal(t, bookRecord.UserID, user.ID, "book user_id mismatch")
+ assert.Equal(t, bookRecord.Label, tc.expectedLabel, "book label mismatch")
+ assert.Equal(t, bookRecord.USN, tc.expectedUSN, "book label mismatch")
+ assert.Equal(t, bookRecord.EditedOn, c.Now().UnixNano(), "book edited_on mismatch")
+ assert.Equal(t, book.UserID, user.ID, "returned book user_id mismatch")
+ assert.Equal(t, book.Label, tc.expectedLabel, "returned book label mismatch")
+ assert.Equal(t, book.USN, tc.expectedUSN, "returned book usn mismatch")
+ assert.Equal(t, book.EditedOn, c.Now().UnixNano(), "returned book edited_on mismatch")
- testutils.AssertEqual(t, userRecord.MaxUSN, tc.expectedUserUSN, "user max_usn mismatch")
+ assert.Equal(t, userRecord.MaxUSN, tc.expectedUserUSN, "user max_usn mismatch")
}()
}
}
diff --git a/server/api/operations/helpers.go b/pkg/server/api/operations/helpers.go
similarity index 96%
rename from server/api/operations/helpers.go
rename to pkg/server/api/operations/helpers.go
index 94ecb09a..7f748191 100644
--- a/server/api/operations/helpers.go
+++ b/pkg/server/api/operations/helpers.go
@@ -19,7 +19,7 @@
package operations
import (
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
)
diff --git a/server/api/operations/helpers_test.go b/pkg/server/api/operations/helpers_test.go
similarity index 83%
rename from server/api/operations/helpers_test.go
rename to pkg/server/api/operations/helpers_test.go
index ea3e62de..cb3bee1e 100644
--- a/server/api/operations/helpers_test.go
+++ b/pkg/server/api/operations/helpers_test.go
@@ -22,8 +22,9 @@ import (
"fmt"
"testing"
- "github.com/dnote/dnote/server/database"
- "github.com/dnote/dnote/server/testutils"
+ "github.com/dnote/dnote/pkg/assert"
+ "github.com/dnote/dnote/pkg/server/database"
+ "github.com/dnote/dnote/pkg/server/testutils"
"github.com/pkg/errors"
)
@@ -67,8 +68,8 @@ func TestIncremenetUserUSN(t *testing.T) {
var userRecord database.User
testutils.MustExec(t, db.Where("id = ?", user.ID).First(&userRecord), fmt.Sprintf("finding user for test case %d", idx))
- testutils.AssertEqual(t, userRecord.MaxUSN, tc.expectedMaxUSN, fmt.Sprintf("user max_usn mismatch for case %d", idx))
- testutils.AssertEqual(t, nextUSN, tc.expectedMaxUSN, fmt.Sprintf("next_usn mismatch for case %d", idx))
+ assert.Equal(t, userRecord.MaxUSN, tc.expectedMaxUSN, fmt.Sprintf("user max_usn mismatch for case %d", idx))
+ assert.Equal(t, nextUSN, tc.expectedMaxUSN, fmt.Sprintf("next_usn mismatch for case %d", idx))
}()
}
}
diff --git a/server/api/operations/notes.go b/pkg/server/api/operations/notes.go
similarity index 95%
rename from server/api/operations/notes.go
rename to pkg/server/api/operations/notes.go
index 7496e94a..8569014e 100644
--- a/server/api/operations/notes.go
+++ b/pkg/server/api/operations/notes.go
@@ -19,9 +19,9 @@
package operations
import (
- "github.com/dnote/dnote/server/api/clock"
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/clock"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
)
diff --git a/server/api/operations/notes_test.go b/pkg/server/api/operations/notes_test.go
similarity index 74%
rename from server/api/operations/notes_test.go
rename to pkg/server/api/operations/notes_test.go
index c97b9467..fb4b4f4b 100644
--- a/server/api/operations/notes_test.go
+++ b/pkg/server/api/operations/notes_test.go
@@ -23,9 +23,10 @@ import (
"testing"
"time"
- "github.com/dnote/dnote/server/api/clock"
- "github.com/dnote/dnote/server/database"
- "github.com/dnote/dnote/server/testutils"
+ "github.com/dnote/dnote/pkg/assert"
+ "github.com/dnote/dnote/pkg/server/api/clock"
+ "github.com/dnote/dnote/pkg/server/database"
+ "github.com/dnote/dnote/pkg/server/testutils"
"github.com/pkg/errors"
)
@@ -105,17 +106,17 @@ func TestCreateNote(t *testing.T) {
testutils.MustExec(t, db.First(¬eRecord), fmt.Sprintf("finding note for test case %d", idx))
testutils.MustExec(t, db.Where("id = ?", user.ID).First(&userRecord), fmt.Sprintf("finding user for test case %d", idx))
- testutils.AssertEqual(t, bookCount, 1, "book count mismatch")
- testutils.AssertEqual(t, noteCount, 1, "note count mismatch")
- testutils.AssertNotEqual(t, noteRecord.UUID, "", "note UUID should have been generated")
- testutils.AssertEqual(t, noteRecord.UserID, user.ID, "note UserID mismatch")
- testutils.AssertEqual(t, noteRecord.Body, "note content", "note Body mismatch")
- testutils.AssertEqual(t, noteRecord.Deleted, false, "note Deleted mismatch")
- testutils.AssertEqual(t, noteRecord.USN, tc.expectedUSN, "note Label mismatch")
- testutils.AssertEqual(t, noteRecord.AddedOn, tc.expectedAddedOn, "note AddedOn mismatch")
- testutils.AssertEqual(t, noteRecord.EditedOn, tc.expectedEditedOn, "note EditedOn mismatch")
+ assert.Equal(t, bookCount, 1, "book count mismatch")
+ assert.Equal(t, noteCount, 1, "note count mismatch")
+ assert.NotEqual(t, noteRecord.UUID, "", "note UUID should have been generated")
+ assert.Equal(t, noteRecord.UserID, user.ID, "note UserID mismatch")
+ assert.Equal(t, noteRecord.Body, "note content", "note Body mismatch")
+ assert.Equal(t, noteRecord.Deleted, false, "note Deleted mismatch")
+ assert.Equal(t, noteRecord.USN, tc.expectedUSN, "note Label mismatch")
+ assert.Equal(t, noteRecord.AddedOn, tc.expectedAddedOn, "note AddedOn mismatch")
+ assert.Equal(t, noteRecord.EditedOn, tc.expectedEditedOn, "note EditedOn mismatch")
- testutils.AssertEqual(t, userRecord.MaxUSN, tc.expectedUSN, "user max_usn mismatch")
+ assert.Equal(t, userRecord.MaxUSN, tc.expectedUSN, "user max_usn mismatch")
}()
}
}
@@ -160,7 +161,7 @@ func TestUpdateNote(t *testing.T) {
content := "updated test content"
tx := db.Begin()
- if _, err := UpdateNote(tx, user, c, note, nil, &content, nil); err != nil {
+ if _, err := UpdateNote(tx, user, c, note, nil, &content); err != nil {
tx.Rollback()
t.Fatal(errors.Wrap(err, "deleting note"))
}
@@ -175,14 +176,14 @@ func TestUpdateNote(t *testing.T) {
testutils.MustExec(t, db.First(¬eRecord), fmt.Sprintf("finding note for test case %d", idx))
testutils.MustExec(t, db.Where("id = ?", user.ID).First(&userRecord), fmt.Sprintf("finding user for test case %d", idx))
- testutils.AssertEqual(t, bookCount, 1, "book count mismatch")
- testutils.AssertEqual(t, noteCount, 1, "note count mismatch")
- testutils.AssertEqual(t, noteRecord.UserID, user.ID, "note UserID mismatch")
- testutils.AssertEqual(t, noteRecord.Body, content, "note Body mismatch")
- testutils.AssertEqual(t, noteRecord.Deleted, false, "note Deleted mismatch")
- testutils.AssertEqual(t, noteRecord.USN, tc.expectedUSN, "note USN mismatch")
+ assert.Equal(t, bookCount, 1, "book count mismatch")
+ assert.Equal(t, noteCount, 1, "note count mismatch")
+ assert.Equal(t, noteRecord.UserID, user.ID, "note UserID mismatch")
+ assert.Equal(t, noteRecord.Body, content, "note Body mismatch")
+ assert.Equal(t, noteRecord.Deleted, false, "note Deleted mismatch")
+ assert.Equal(t, noteRecord.USN, tc.expectedUSN, "note USN mismatch")
- testutils.AssertEqual(t, userRecord.MaxUSN, tc.expectedUSN, "user MaxUSN mismatch")
+ assert.Equal(t, userRecord.MaxUSN, tc.expectedUSN, "user MaxUSN mismatch")
}()
}
}
@@ -239,18 +240,18 @@ func TestDeleteNote(t *testing.T) {
testutils.MustExec(t, db.First(¬eRecord), fmt.Sprintf("finding note for test case %d", idx))
testutils.MustExec(t, db.Where("id = ?", user.ID).First(&userRecord), fmt.Sprintf("finding user for test case %d", idx))
- testutils.AssertEqual(t, noteCount, 1, "note count mismatch")
+ assert.Equal(t, noteCount, 1, "note count mismatch")
- testutils.AssertEqual(t, noteRecord.UserID, user.ID, "note user_id mismatch")
- testutils.AssertEqual(t, noteRecord.Body, "", "note content mismatch")
- testutils.AssertEqual(t, noteRecord.Deleted, true, "note deleted flag mismatch")
- testutils.AssertEqual(t, noteRecord.USN, tc.expectedUSN, "note label mismatch")
- testutils.AssertEqual(t, userRecord.MaxUSN, tc.expectedUSN, "user max_usn mismatch")
+ assert.Equal(t, noteRecord.UserID, user.ID, "note user_id mismatch")
+ assert.Equal(t, noteRecord.Body, "", "note content mismatch")
+ assert.Equal(t, noteRecord.Deleted, true, "note deleted flag mismatch")
+ assert.Equal(t, noteRecord.USN, tc.expectedUSN, "note label mismatch")
+ assert.Equal(t, userRecord.MaxUSN, tc.expectedUSN, "user max_usn mismatch")
- testutils.AssertEqual(t, ret.UserID, user.ID, "note user_id mismatch")
- testutils.AssertEqual(t, ret.Body, "", "note content mismatch")
- testutils.AssertEqual(t, ret.Deleted, true, "note deleted flag mismatch")
- testutils.AssertEqual(t, ret.USN, tc.expectedUSN, "note label mismatch")
+ assert.Equal(t, ret.UserID, user.ID, "note user_id mismatch")
+ assert.Equal(t, ret.Body, "", "note content mismatch")
+ assert.Equal(t, ret.Deleted, true, "note deleted flag mismatch")
+ assert.Equal(t, ret.USN, tc.expectedUSN, "note label mismatch")
}()
}
}
diff --git a/server/api/operations/sessions.go b/pkg/server/api/operations/sessions.go
similarity index 95%
rename from server/api/operations/sessions.go
rename to pkg/server/api/operations/sessions.go
index 07e7237c..d9fb6cb6 100644
--- a/server/api/operations/sessions.go
+++ b/pkg/server/api/operations/sessions.go
@@ -23,8 +23,8 @@ import (
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
- "github.com/dnote/dnote/server/api/crypt"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/crypt"
+ "github.com/dnote/dnote/pkg/server/database"
)
// CreateSession returns a new session for the user of the given id
diff --git a/server/api/operations/subscriptions.go b/pkg/server/api/operations/subscriptions.go
similarity index 98%
rename from server/api/operations/subscriptions.go
rename to pkg/server/api/operations/subscriptions.go
index 6eb60e34..e24da365 100644
--- a/server/api/operations/subscriptions.go
+++ b/pkg/server/api/operations/subscriptions.go
@@ -19,7 +19,7 @@
package operations
import (
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/pkg/errors"
"github.com/stripe/stripe-go"
diff --git a/server/api/operations/users.go b/pkg/server/api/operations/users.go
similarity index 97%
rename from server/api/operations/users.go
rename to pkg/server/api/operations/users.go
index bff6f762..486bfd9d 100644
--- a/server/api/operations/users.go
+++ b/pkg/server/api/operations/users.go
@@ -21,8 +21,8 @@ package operations
import (
"time"
- "github.com/dnote/dnote/server/api/crypt"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/crypt"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
)
diff --git a/server/api/presenters/presenters.go b/pkg/server/api/presenters/presenters.go
similarity index 98%
rename from server/api/presenters/presenters.go
rename to pkg/server/api/presenters/presenters.go
index 4074c835..b1eec729 100644
--- a/server/api/presenters/presenters.go
+++ b/pkg/server/api/presenters/presenters.go
@@ -21,7 +21,7 @@ package presenters
import (
"time"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/database"
)
// formatTs rounds up the given timestamp to the microsecond
diff --git a/server/api/scripts/dev.sh b/pkg/server/api/scripts/dev.sh
similarity index 86%
rename from server/api/scripts/dev.sh
rename to pkg/server/api/scripts/dev.sh
index bbbbfe19..5293b7ee 100755
--- a/server/api/scripts/dev.sh
+++ b/pkg/server/api/scripts/dev.sh
@@ -3,7 +3,7 @@
# usage: DOTENV_PATH=path_to_dotenv_file EMAIL_TEMPLATE_DIR=path_to_email_templates ./dev.sh
set -eux
-basePath="$GOPATH/src/github.com/dnote/dnote/server"
+basePath="$GOPATH/src/github.com/dnote/dnote/pkg/server"
# load env
export $(cat "$DOTENV_PATH" | xargs)
diff --git a/server/api/scripts/makeDemoDigests/main.go b/pkg/server/api/scripts/makeDemoDigests/main.go
similarity index 98%
rename from server/api/scripts/makeDemoDigests/main.go
rename to pkg/server/api/scripts/makeDemoDigests/main.go
index d00a8059..0ba4d4be 100644
--- a/server/api/scripts/makeDemoDigests/main.go
+++ b/pkg/server/api/scripts/makeDemoDigests/main.go
@@ -19,8 +19,8 @@
package main
import (
- "github.com/dnote/dnote/server/api/helpers"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/api/helpers"
+ "github.com/dnote/dnote/pkg/server/database"
"time"
)
diff --git a/server/api/scripts/setup.sh b/pkg/server/api/scripts/setup.sh
similarity index 100%
rename from server/api/scripts/setup.sh
rename to pkg/server/api/scripts/setup.sh
diff --git a/server/api/scripts/test-local.sh b/pkg/server/api/scripts/test-local.sh
similarity index 71%
rename from server/api/scripts/test-local.sh
rename to pkg/server/api/scripts/test-local.sh
index 4ec48692..ebe8b7bd 100755
--- a/server/api/scripts/test-local.sh
+++ b/pkg/server/api/scripts/test-local.sh
@@ -2,7 +2,7 @@
# test-local.sh runs api tests using local setting
set -eux
-basePath=$GOPATH/src/github.com/dnote/dnote/server/api
+basePath=$GOPATH/src/github.com/dnote/dnote/pkg/server/api
export $(cat "$basePath"/.env.test | xargs)
"$basePath"/scripts/test.sh
diff --git a/server/api/scripts/test.sh b/pkg/server/api/scripts/test.sh
similarity index 75%
rename from server/api/scripts/test.sh
rename to pkg/server/api/scripts/test.sh
index 48b78eb3..6e9d3fa8 100755
--- a/server/api/scripts/test.sh
+++ b/pkg/server/api/scripts/test.sh
@@ -3,6 +3,6 @@
# appropriate env vars.
set -eux
-pushd "$GOPATH"/src/github.com/dnote/dnote/server/api
+pushd "$GOPATH"/src/github.com/dnote/dnote/pkg/server/api
go test ./handlers/... ./operations/... -cover -p 1
popd
diff --git a/server/database/main.go b/pkg/server/database/main.go
similarity index 100%
rename from server/database/main.go
rename to pkg/server/database/main.go
diff --git a/server/database/models.go b/pkg/server/database/models.go
similarity index 100%
rename from server/database/models.go
rename to pkg/server/database/models.go
diff --git a/server/database/types.go b/pkg/server/database/types.go
similarity index 100%
rename from server/database/types.go
rename to pkg/server/database/types.go
diff --git a/server/job/.env.dev b/pkg/server/job/.env.dev
similarity index 100%
rename from server/job/.env.dev
rename to pkg/server/job/.env.dev
diff --git a/server/job/.gitignore b/pkg/server/job/.gitignore
similarity index 100%
rename from server/job/.gitignore
rename to pkg/server/job/.gitignore
diff --git a/server/job/digest/digest.go b/pkg/server/job/digest/digest.go
similarity index 97%
rename from server/job/digest/digest.go
rename to pkg/server/job/digest/digest.go
index e78108cf..5446eb0d 100644
--- a/server/job/digest/digest.go
+++ b/pkg/server/job/digest/digest.go
@@ -22,8 +22,8 @@ import (
"log"
"time"
- "github.com/dnote/dnote/server/database"
- "github.com/dnote/dnote/server/mailer"
+ "github.com/dnote/dnote/pkg/server/database"
+ "github.com/dnote/dnote/pkg/server/mailer"
"github.com/pkg/errors"
)
diff --git a/server/job/main.go b/pkg/server/job/main.go
similarity index 92%
rename from server/job/main.go
rename to pkg/server/job/main.go
index d3bfcff0..93f95bae 100644
--- a/server/job/main.go
+++ b/pkg/server/job/main.go
@@ -23,9 +23,9 @@ import (
"log"
"os"
- "github.com/dnote/dnote/server/database"
- "github.com/dnote/dnote/server/job/digest"
- "github.com/dnote/dnote/server/mailer"
+ "github.com/dnote/dnote/pkg/server/database"
+ "github.com/dnote/dnote/pkg/server/job/digest"
+ "github.com/dnote/dnote/pkg/server/mailer"
"github.com/joho/godotenv"
_ "github.com/lib/pq"
diff --git a/server/job/scripts/dev.sh b/pkg/server/job/scripts/dev.sh
similarity index 100%
rename from server/job/scripts/dev.sh
rename to pkg/server/job/scripts/dev.sh
diff --git a/server/mailer/mailer.go b/pkg/server/mailer/mailer.go
similarity index 100%
rename from server/mailer/mailer.go
rename to pkg/server/mailer/mailer.go
diff --git a/server/mailer/templates/.env.dev b/pkg/server/mailer/templates/.env.dev
similarity index 100%
rename from server/mailer/templates/.env.dev
rename to pkg/server/mailer/templates/.env.dev
diff --git a/server/mailer/templates/.gitignore b/pkg/server/mailer/templates/.gitignore
similarity index 100%
rename from server/mailer/templates/.gitignore
rename to pkg/server/mailer/templates/.gitignore
diff --git a/server/mailer/templates/README.md b/pkg/server/mailer/templates/README.md
similarity index 100%
rename from server/mailer/templates/README.md
rename to pkg/server/mailer/templates/README.md
diff --git a/server/mailer/templates/main.go b/pkg/server/mailer/templates/main.go
similarity index 94%
rename from server/mailer/templates/main.go
rename to pkg/server/mailer/templates/main.go
index 24c12091..39048e6c 100644
--- a/server/mailer/templates/main.go
+++ b/pkg/server/mailer/templates/main.go
@@ -22,9 +22,9 @@ import (
"log"
"net/http"
- "github.com/dnote/dnote/server/database"
- "github.com/dnote/dnote/server/job/digest"
- "github.com/dnote/dnote/server/mailer"
+ "github.com/dnote/dnote/pkg/server/database"
+ "github.com/dnote/dnote/pkg/server/job/digest"
+ "github.com/dnote/dnote/pkg/server/mailer"
"github.com/joho/godotenv"
_ "github.com/lib/pq"
"github.com/pkg/errors"
diff --git a/server/mailer/templates/scripts/run.sh b/pkg/server/mailer/templates/scripts/run.sh
similarity index 100%
rename from server/mailer/templates/scripts/run.sh
rename to pkg/server/mailer/templates/scripts/run.sh
diff --git a/server/mailer/templates/src/email_verification.html b/pkg/server/mailer/templates/src/email_verification.html
similarity index 100%
rename from server/mailer/templates/src/email_verification.html
rename to pkg/server/mailer/templates/src/email_verification.html
diff --git a/server/mailer/templates/src/footer.html b/pkg/server/mailer/templates/src/footer.html
similarity index 100%
rename from server/mailer/templates/src/footer.html
rename to pkg/server/mailer/templates/src/footer.html
diff --git a/server/mailer/templates/src/header.html b/pkg/server/mailer/templates/src/header.html
similarity index 100%
rename from server/mailer/templates/src/header.html
rename to pkg/server/mailer/templates/src/header.html
diff --git a/server/mailer/templates/src/reset_password.html b/pkg/server/mailer/templates/src/reset_password.html
similarity index 100%
rename from server/mailer/templates/src/reset_password.html
rename to pkg/server/mailer/templates/src/reset_password.html
diff --git a/server/mailer/templates/src/weekly_digest.html b/pkg/server/mailer/templates/src/weekly_digest.html
similarity index 100%
rename from server/mailer/templates/src/weekly_digest.html
rename to pkg/server/mailer/templates/src/weekly_digest.html
diff --git a/server/mailer/types.go b/pkg/server/mailer/types.go
similarity index 100%
rename from server/mailer/types.go
rename to pkg/server/mailer/types.go
diff --git a/server/mailer/utils.go b/pkg/server/mailer/utils.go
similarity index 97%
rename from server/mailer/utils.go
rename to pkg/server/mailer/utils.go
index 1fb91ab4..e0510291 100644
--- a/server/mailer/utils.go
+++ b/pkg/server/mailer/utils.go
@@ -22,7 +22,7 @@ import (
"crypto/rand"
"encoding/base64"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/pkg/errors"
)
diff --git a/server/testutils/main.go b/pkg/server/testutils/main.go
similarity index 68%
rename from server/testutils/main.go
rename to pkg/server/testutils/main.go
index 301a37e2..b049dd30 100644
--- a/server/testutils/main.go
+++ b/pkg/server/testutils/main.go
@@ -22,122 +22,19 @@ package testutils
import (
"encoding/json"
"fmt"
- "io/ioutil"
"net/http"
"net/http/httptest"
- "reflect"
"strings"
"testing"
"time"
- "github.com/dnote/dnote/server/database"
+ "github.com/dnote/dnote/pkg/server/database"
"github.com/stripe/stripe-go"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
)
-func checkEqual(a interface{}, b interface{}, message string) (bool, string) {
- if a == b {
- return true, ""
- }
-
- var m string
- if len(message) == 0 {
- m = fmt.Sprintf("%v != %v", a, b)
- } else {
- m = message
- }
- errorMessage := fmt.Sprintf("%s. Actual: %+v. Expected: %+v.", m, a, b)
-
- return false, errorMessage
-}
-
-// AssertEqual errors a test if the actual does not match the expected
-func AssertEqual(t *testing.T, a interface{}, b interface{}, message string) {
- ok, m := checkEqual(a, b, message)
- if !ok {
- t.Error(m)
- }
-}
-
-// AssertEqualf fails a test if the actual does not match the expected
-func AssertEqualf(t *testing.T, a interface{}, b interface{}, message string) {
- ok, m := checkEqual(a, b, message)
- if !ok {
- t.Fatal(m)
- }
-}
-
-// AssertNotEqual fails a test if the actual matches the expected
-func AssertNotEqual(t *testing.T, a interface{}, b interface{}, message string) {
- if a != b {
- return
- }
- if len(message) == 0 {
- message = fmt.Sprintf("%v != %v", a, b)
- }
- t.Errorf("%s. Expected %+v to not equal %+v.", message, a, b)
-}
-
-// AssertDeepEqual fails a test if the actual does not deeply equal the expected
-func AssertDeepEqual(t *testing.T, a interface{}, b interface{}, message string) {
- if reflect.DeepEqual(a, b) {
- return
- }
-
- if len(message) == 0 {
- message = fmt.Sprintf("%v != %v", a, b)
- }
- t.Errorf("%s.\nActual: %+v.\nExpected: %+v.", message, a, b)
-}
-
-// AssertEqualJSON asserts that two JSON strings are equal
-func AssertEqualJSON(t *testing.T, a, b, message string) {
- var o1 interface{}
- var o2 interface{}
-
- err := json.Unmarshal([]byte(a), &o1)
- if err != nil {
- panic(fmt.Errorf("Error mashalling string 1 :: %s", err.Error()))
- }
- err = json.Unmarshal([]byte(b), &o2)
- if err != nil {
- panic(fmt.Errorf("Error mashalling string 2 :: %s", err.Error()))
- }
-
- if reflect.DeepEqual(o1, o2) {
- return
- }
-
- if len(message) == 0 {
- message = fmt.Sprintf("%v != %v", a, b)
- }
- t.Errorf("%s.\nActual: %+v.\nExpected: %+v.", message, a, b)
-}
-
-// ReadJSON reads JSON fixture to the struct at the destination address
-func ReadJSON(path string, destination interface{}) {
- var dat []byte
- dat, err := ioutil.ReadFile(path)
- if err != nil {
- panic(errors.Wrap(err, "reading file"))
- }
- if err := json.Unmarshal(dat, destination); err != nil {
- panic(errors.Wrap(err, "unmarshalling json"))
- }
-}
-
-// ReadFile reads file and returns the byte
-func ReadFile(path string) []byte {
- dat, err := ioutil.ReadFile(path)
- if err != nil {
- panic(errors.Wrap(err, "reading file"))
- }
-
- return dat
-}
-
// InitTestDB establishes connection pool with the test database specified by
// the environment variable configuration and initalizes a new schema
func InitTestDB() {
@@ -304,19 +201,6 @@ func MakeReq(server *httptest.Server, method, url, data string) *http.Request {
return req
}
-// AssertStatusCode asserts that the reponse's status code is equal to the
-// expected
-func AssertStatusCode(t *testing.T, res *http.Response, expected int, message string) {
- if res.StatusCode != expected {
- body, err := ioutil.ReadAll(res.Body)
- if err != nil {
- panic(errors.Wrap(err, "reading body"))
- }
-
- t.Errorf("status code mismatch. %s: got %v want %v. Message was: '%s'", message, res.StatusCode, expected, string(body))
- }
-}
-
// MustExec fails the test if the given database query has error
func MustExec(t *testing.T, db *gorm.DB, message string) {
if err := db.Error; err != nil {
@@ -324,17 +208,6 @@ func MustExec(t *testing.T, db *gorm.DB, message string) {
}
}
-// MustMarshalJSON marshalls the given interface into JSON.
-// If there is any error, it fails the test.
-func MustMarshalJSON(t *testing.T, v interface{}) []byte {
- b, err := json.Marshal(v)
- if err != nil {
- t.Fatal("marshalling data")
- }
-
- return b
-}
-
// GetCookieByName returns a cookie with the given name
func GetCookieByName(cookies []*http.Cookie, name string) *http.Cookie {
var ret *http.Cookie
diff --git a/scripts/license.sh b/scripts/license.sh
index 6f62e52f..90655f79 100755
--- a/scripts/license.sh
+++ b/scripts/license.sh
@@ -54,19 +54,20 @@ agpl="/* Copyright (C) 2019 Monomax Software Pty Ltd
* along with Dnote. If not, see .
*/"
-cliPath="$GOPATH"/src/github.com/dnote/dnote/cli
-cliFiles=$(find "$cliPath" -type f -name "*.go" ! -path "**/vendor/*")
+pkgPath="$GOPATH"/src/github.com/dnote/dnote/pkg
+serverPath="$GOPATH"/src/github.com/dnote/dnote/pkg/server
-for file in $cliFiles; do
+pkgFiles=$(find "$pkgPath" -type f -name "*.go" ! -path "**/vendor/*" ! -path "$serverPath/*")
+
+for file in $pkgFiles; do
remove_notice "$file"
add_notice "$file" "$gpl"
done
- serverPath="$GOPATH"/src/github.com/dnote/dnote/server
- webPath="$GOPATH"/src/github.com/dnote/dnote/web
- agplFiles=$(find "$serverPath" "$webPath" -type f \( -name "*.go" -o -name "*.js" -o -name "*.scss" \) ! -path "**/vendor/*" ! -path "**/node_modules/*")
-
- for file in $agplFiles; do
- remove_notice "$file"
- add_notice "$file" "$agpl"
- done
+webPath="$GOPATH"/src/github.com/dnote/dnote/web
+agplFiles=$(find "$serverPath" "$webPath" -type f \( -name "*.go" -o -name "*.js" -o -name "*.scss" \) ! -path "**/vendor/*" ! -path "**/node_modules/*")
+
+for file in $agplFiles; do
+ remove_notice "$file"
+ add_notice "$file" "$agpl"
+done