Add ConfigCommand test #58
- Includes refactoring of existing packages to enable testing of commands
This commit is contained in:
parent
86a6dda0e0
commit
9872cfaa50
|
@ -7,13 +7,13 @@ import (
|
|||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Prints current configuration
|
||||
var ConfigCommand = cli.Command{
|
||||
Name: "config",
|
||||
Usage: "Displays global configuration values",
|
||||
Action: configAction,
|
||||
}
|
||||
|
||||
// Prints current configuration; called by ConfigCommand
|
||||
func configAction(ctx *cli.Context) error {
|
||||
conf := context.NewConfig(ctx)
|
||||
|
||||
|
|
34
internal/commands/config_test.go
Normal file
34
internal/commands/config_test.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestConfigCommand(t *testing.T) {
|
||||
var err error
|
||||
|
||||
ctx := test.CliContext()
|
||||
|
||||
output := test.Capture(func() {
|
||||
err = ConfigCommand.Run(ctx)
|
||||
})
|
||||
|
||||
expected := `NAME VALUE
|
||||
debug false
|
||||
config-file /go/src/github.com/photoprism/photoprism/configs/photoprism.yml
|
||||
darktable-cli /usr/bin/darktable-cli
|
||||
originals-path /go/src/github.com/photoprism/photoprism/assets/testdata/originals
|
||||
import-path /srv/photoprism/photos/import
|
||||
export-path /srv/photoprism/photos/export
|
||||
cache-path /srv/photoprism/cache
|
||||
assets-path /go/src/github.com/photoprism/photoprism/assets
|
||||
database-driver mysql
|
||||
database-dsn photoprism:photoprism@tcp(database:3306)/photoprism?parseTime=true
|
||||
`
|
||||
|
||||
assert.Equal(t, expected, output)
|
||||
assert.Nil(t, err)
|
||||
}
|
|
@ -9,13 +9,13 @@ import (
|
|||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Converts RAW files to JPEG images, if no JPEG already exists
|
||||
var ConvertCommand = cli.Command{
|
||||
Name: "convert",
|
||||
Usage: "Converts RAW originals to JPEG",
|
||||
Action: convertAction,
|
||||
}
|
||||
|
||||
// Converts images to JPEG; called by ConvertCommand
|
||||
func convertAction(ctx *cli.Context) error {
|
||||
conf := context.NewConfig(ctx)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
This package contains commands and flags to be used by the main application.
|
||||
This package contains commands and flags used by the photoprism application.
|
||||
|
||||
Additional information concerning the command-line interface can be found in our Developer Guide:
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Exports photos as JPEG thumbnails (resized)
|
||||
var ExportCommand = cli.Command{
|
||||
Name: "export",
|
||||
Usage: "Exports photos as JPEG",
|
||||
|
@ -37,7 +38,6 @@ var exportFlags = []cli.Flag{
|
|||
},
|
||||
}
|
||||
|
||||
// Exports photos as JPEG; called by ExportCommand and uses exportFlags
|
||||
func exportAction(ctx *cli.Context) error {
|
||||
conf := context.NewConfig(ctx)
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package commands
|
|||
|
||||
import "github.com/urfave/cli"
|
||||
|
||||
// Global CLI flags
|
||||
var GlobalFlags = []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
|
|
|
@ -9,13 +9,13 @@ import (
|
|||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Imports photos from path defined in command-line args
|
||||
var ImportCommand = cli.Command{
|
||||
Name: "import",
|
||||
Usage: "Imports photos",
|
||||
Action: importAction,
|
||||
}
|
||||
|
||||
// Imports photos from path defined in ctx arg; called by ImportCommand;
|
||||
func importAction(ctx *cli.Context) error {
|
||||
conf := context.NewConfig(ctx)
|
||||
|
||||
|
|
|
@ -9,13 +9,13 @@ import (
|
|||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Re-indexes all photos in originals directory (photo library)
|
||||
var IndexCommand = cli.Command{
|
||||
Name: "index",
|
||||
Usage: "Re-indexes all originals",
|
||||
Action: indexAction,
|
||||
}
|
||||
|
||||
// Indexes original photos; called by IndexCommand
|
||||
func indexAction(ctx *cli.Context) error {
|
||||
conf := context.NewConfig(ctx)
|
||||
|
||||
|
|
|
@ -7,13 +7,13 @@ import (
|
|||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Automatically migrates / initializes database
|
||||
var MigrateCommand = cli.Command{
|
||||
Name: "migrate",
|
||||
Usage: "Automatically migrates / initializes database",
|
||||
Action: migrateAction,
|
||||
}
|
||||
|
||||
// Automatically migrates / initializes database; called by MigrateCommand
|
||||
func migrateAction(ctx *cli.Context) error {
|
||||
conf := context.NewConfig(ctx)
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Starts web server (user interface)
|
||||
var StartCommand = cli.Command{
|
||||
Name: "start",
|
||||
Usage: "Starts web server",
|
||||
|
@ -37,7 +38,6 @@ var startFlags = []cli.Flag{
|
|||
},
|
||||
}
|
||||
|
||||
// Starts web serve using startFlags; called by startCommand
|
||||
func startAction(ctx *cli.Context) error {
|
||||
conf := context.NewConfig(ctx)
|
||||
|
||||
|
|
|
@ -9,9 +9,10 @@ import (
|
|||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Pre-renders thumbnails
|
||||
var ThumbnailsCommand = cli.Command{
|
||||
Name: "thumbnails",
|
||||
Usage: "Creates thumbnails",
|
||||
Usage: "Pre-renders thumbnails",
|
||||
Flags: []cli.Flag{
|
||||
cli.IntSliceFlag{
|
||||
Name: "size, s",
|
||||
|
@ -29,7 +30,6 @@ var ThumbnailsCommand = cli.Command{
|
|||
Action: thumbnailsAction,
|
||||
}
|
||||
|
||||
// Creates thumbnail; called by ThumbnailsCommand
|
||||
func thumbnailsAction(ctx *cli.Context) error {
|
||||
conf := context.NewConfig(ctx)
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||
"github.com/kylelemons/go-gypsy/yaml"
|
||||
"github.com/photoprism/photoprism/internal/frontend"
|
||||
"github.com/photoprism/photoprism/internal/fsutil"
|
||||
"github.com/photoprism/photoprism/internal/models"
|
||||
"github.com/urfave/cli"
|
||||
|
@ -42,8 +43,6 @@ type Config struct {
|
|||
db *gorm.DB
|
||||
}
|
||||
|
||||
type ClientConfig map[string]interface{}
|
||||
|
||||
// NewConfig() creates a new configuration entity by using two methods:
|
||||
//
|
||||
// 1. SetValuesFromFile: This will initialize values from a yaml config file.
|
||||
|
@ -386,7 +385,7 @@ func (c *Config) MigrateDb() {
|
|||
}
|
||||
|
||||
// GetClientConfig returns a loaded and set configuration entity.
|
||||
func (c *Config) GetClientConfig() map[string]interface{} {
|
||||
func (c *Config) GetClientConfig() frontend.Config {
|
||||
db := c.GetDb()
|
||||
|
||||
var cameras []*models.Camera
|
||||
|
@ -405,7 +404,7 @@ func (c *Config) GetClientConfig() map[string]interface{} {
|
|||
jsHash := fsutil.Hash(c.GetPublicBuildPath() + "/app.js")
|
||||
cssHash := fsutil.Hash(c.GetPublicBuildPath() + "/app.css")
|
||||
|
||||
result := ClientConfig{
|
||||
result := frontend.Config{
|
||||
"appName": c.GetAppName(),
|
||||
"appVersion": c.GetAppVersion(),
|
||||
"debug": c.IsDebug(),
|
||||
|
|
|
@ -1,46 +1,16 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/fsutil"
|
||||
"github.com/photoprism/photoprism/internal/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
const testDataPath = "testdata"
|
||||
const testConfigFile = "../../configs/photoprism.yml"
|
||||
|
||||
var darktableCli = "/usr/bin/darktable-cli"
|
||||
var assetsPath = fsutil.ExpandedFilename("../../assets")
|
||||
var originalsPath = fsutil.ExpandedFilename(testDataPath + "/originals")
|
||||
var databaseDriver = "mysql"
|
||||
var databaseDsn = "photoprism:photoprism@tcp(database:3306)/photoprism?parseTime=true"
|
||||
|
||||
func getTestCliContext() *cli.Context {
|
||||
globalSet := flag.NewFlagSet("test", 0)
|
||||
globalSet.Bool("debug", false, "doc")
|
||||
globalSet.String("config-file", testConfigFile, "doc")
|
||||
globalSet.String("assets-path", assetsPath, "doc")
|
||||
globalSet.String("originals-path", originalsPath, "doc")
|
||||
globalSet.String("darktable-cli", darktableCli, "doc")
|
||||
|
||||
app := cli.NewApp()
|
||||
|
||||
c := cli.NewContext(app, globalSet, nil)
|
||||
|
||||
c.Set("config-file", testConfigFile)
|
||||
c.Set("assets-path", assetsPath)
|
||||
c.Set("originals-path", originalsPath)
|
||||
c.Set("darktable-cli", darktableCli)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func TestNewConfig(t *testing.T) {
|
||||
ctx := getTestCliContext()
|
||||
ctx := test.CliContext()
|
||||
|
||||
assert.True(t, ctx.IsSet("assets-path"))
|
||||
assert.False(t, ctx.Bool("debug"))
|
||||
|
@ -49,14 +19,14 @@ func TestNewConfig(t *testing.T) {
|
|||
|
||||
assert.IsType(t, new(Config), c)
|
||||
|
||||
assert.Equal(t, assetsPath, c.GetAssetsPath())
|
||||
assert.Equal(t, fsutil.ExpandedFilename("../../assets"), c.GetAssetsPath())
|
||||
assert.False(t, c.IsDebug())
|
||||
}
|
||||
|
||||
func TestConfig_SetValuesFromFile(t *testing.T) {
|
||||
c := NewConfig(getTestCliContext())
|
||||
c := NewConfig(test.CliContext())
|
||||
|
||||
c.SetValuesFromFile(fsutil.ExpandedFilename(testConfigFile))
|
||||
c.SetValuesFromFile(fsutil.ExpandedFilename("../../configs/photoprism.yml"))
|
||||
|
||||
assert.Equal(t, "/srv/photoprism", c.GetAssetsPath())
|
||||
assert.Equal(t, "/srv/photoprism/cache", c.GetCachePath())
|
||||
|
@ -64,6 +34,6 @@ func TestConfig_SetValuesFromFile(t *testing.T) {
|
|||
assert.Equal(t, "/srv/photoprism/photos/originals", c.GetOriginalsPath())
|
||||
assert.Equal(t, "/srv/photoprism/photos/import", c.GetImportPath())
|
||||
assert.Equal(t, "/srv/photoprism/photos/export", c.GetExportPath())
|
||||
assert.Equal(t, databaseDriver, c.GetDatabaseDriver())
|
||||
assert.Equal(t, databaseDsn, c.GetDatabaseDsn())
|
||||
assert.Equal(t, "mysql", c.GetDatabaseDriver())
|
||||
assert.Equal(t, "photoprism:photoprism@tcp(database:3306)/photoprism?parseTime=true", c.GetDatabaseDsn())
|
||||
}
|
||||
|
|
4
internal/frontend/config.go
Normal file
4
internal/frontend/config.go
Normal file
|
@ -0,0 +1,4 @@
|
|||
package frontend
|
||||
|
||||
// Config values for Web frontend
|
||||
type Config map[string]interface{}
|
8
internal/frontend/doc.go
Normal file
8
internal/frontend/doc.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
Package frontend contains user interface related code.
|
||||
|
||||
Additional information can be found in our Developer Guide:
|
||||
|
||||
https://github.com/photoprism/photoprism/wiki
|
||||
*/
|
||||
package frontend
|
|
@ -4,14 +4,16 @@ import (
|
|||
"github.com/jinzhu/gorm"
|
||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||
"github.com/photoprism/photoprism/internal/frontend"
|
||||
)
|
||||
|
||||
// Todo: Remove Get prefix, see https://golang.org/doc/effective_go.html#Getters
|
||||
type Config interface {
|
||||
CreateDirectories() error
|
||||
MigrateDb()
|
||||
|
||||
GetDb() *gorm.DB
|
||||
GetClientConfig() map[string]interface{}
|
||||
GetClientConfig() frontend.Config
|
||||
|
||||
GetConfigFile() string
|
||||
GetAppName() string
|
||||
|
|
35
internal/test/capture.go
Normal file
35
internal/test/capture.go
Normal file
|
@ -0,0 +1,35 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Returns output to stdout and stderr for testing
|
||||
func Capture(f func()) string {
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
stdout := os.Stdout
|
||||
os.Stdout = w
|
||||
defer func() {
|
||||
os.Stdout = stdout
|
||||
}()
|
||||
|
||||
stderr := os.Stderr
|
||||
os.Stderr = w
|
||||
defer func() {
|
||||
os.Stderr = stderr
|
||||
}()
|
||||
|
||||
f()
|
||||
w.Close()
|
||||
|
||||
var buf bytes.Buffer
|
||||
io.Copy(&buf, r)
|
||||
|
||||
return buf.String()
|
||||
}
|
18
internal/test/capture_test.go
Normal file
18
internal/test/capture_test.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCapture(t *testing.T) {
|
||||
result := Capture(func() {
|
||||
fmt.Fprint(os.Stdout, "foo")
|
||||
fmt.Fprint(os.Stderr, "bar")
|
||||
})
|
||||
|
||||
assert.Equal(t, "foobar", result)
|
||||
}
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/jinzhu/gorm"
|
||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||
"github.com/photoprism/photoprism/internal/context"
|
||||
"github.com/photoprism/photoprism/internal/frontend"
|
||||
"github.com/photoprism/photoprism/internal/fsutil"
|
||||
"github.com/photoprism/photoprism/internal/models"
|
||||
)
|
||||
|
@ -296,7 +296,7 @@ func (c *Config) MigrateDb() {
|
|||
}
|
||||
|
||||
// GetClientConfig returns a loaded and set configuration entity.
|
||||
func (c *Config) GetClientConfig() map[string]interface{} {
|
||||
func (c *Config) GetClientConfig() frontend.Config {
|
||||
db := c.GetDb()
|
||||
|
||||
var cameras []*models.Camera
|
||||
|
@ -315,7 +315,7 @@ func (c *Config) GetClientConfig() map[string]interface{} {
|
|||
jsHash := fsutil.Hash(c.GetPublicBuildPath() + "/app.js")
|
||||
cssHash := fsutil.Hash(c.GetPublicBuildPath() + "/app.css")
|
||||
|
||||
result := context.ClientConfig{
|
||||
result := frontend.Config{
|
||||
"appName": c.GetAppName(),
|
||||
"appVersion": c.GetAppVersion(),
|
||||
"debug": c.IsDebug(),
|
||||
|
|
28
internal/test/context.go
Normal file
28
internal/test/context.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Returns example cli context for testing
|
||||
func CliContext() *cli.Context {
|
||||
globalSet := flag.NewFlagSet("test", 0)
|
||||
globalSet.Bool("debug", false, "doc")
|
||||
globalSet.String("config-file", ConfigFile, "doc")
|
||||
globalSet.String("assets-path", AssetsPath, "doc")
|
||||
globalSet.String("originals-path", OriginalsPath, "doc")
|
||||
globalSet.String("darktable-cli", DarktableCli, "doc")
|
||||
|
||||
app := cli.NewApp()
|
||||
|
||||
c := cli.NewContext(app, globalSet, nil)
|
||||
|
||||
c.Set("config-file", ConfigFile)
|
||||
c.Set("assets-path", AssetsPath)
|
||||
c.Set("originals-path", OriginalsPath)
|
||||
c.Set("darktable-cli", DarktableCli)
|
||||
|
||||
return c
|
||||
}
|
14
internal/test/context_test.go
Normal file
14
internal/test/context_test.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func TestCliContext(t *testing.T) {
|
||||
result := CliContext()
|
||||
|
||||
assert.IsType(t, new(cli.Context), result)
|
||||
}
|
Loading…
Reference in a new issue