diff --git a/cmd/app.go b/cmd/app.go index 9cd25fe..e7e330b 100644 --- a/cmd/app.go +++ b/cmd/app.go @@ -1,6 +1,7 @@ package cmd import ( + "bytes" "fmt" "io" "os" @@ -117,12 +118,15 @@ func outputHostsfile(hf *hostsfile.Hosts, all bool) { } } - lineOutput := fmt.Sprintf("%s\n", line.Raw) + lineOutput := line.Raw if line.IsMalformed() { - lineOutput = fmt.Sprintf("%s # <<< Malformed!\n", lineOutput) + logrus.Debugf("malformed line: %s", line.Err) + if !line.HasComment() { + lineOutput = fmt.Sprintf("%s #", lineOutput) + } + lineOutput = fmt.Sprintf("%s <<< Malformed!", lineOutput) } - - logrus.Infof(lineOutput) + logrus.Info(lineOutput + "\n") } } @@ -166,13 +170,15 @@ func debugFooter(c *cli.Context) error { {"malformed", fmt.Sprintf("%d", malformed)}, } - table := tablewriter.NewWriter(os.Stdout) + buf := &bytes.Buffer{} + table := tablewriter.NewWriter(buf) table.SetHeader([]string{"Type", "Count"}) for _, v := range data { table.Append(v) } table.Render() + logrus.Info(buf) return nil } diff --git a/cmd/app_test.go b/cmd/app_test.go index 991b865..bc6c476 100644 --- a/cmd/app_test.go +++ b/cmd/app_test.go @@ -11,7 +11,7 @@ import ( easy "github.com/t-tomalak/logrus-easy-formatter" ) -func TestDebug(t *testing.T) { +func TestDebugFlag(t *testing.T) { args, out := setup("--debug", "version") Version("test-version", "test-commit", "test-date") assert.Nil(t, App.Run(args)) @@ -47,10 +47,10 @@ func read(t *testing.T, name, file string) func() { } } -//func write(t *testing.T, name, file string) func() { -// err := os.WriteFile(name, []byte(file), 0770) -// assert.Nil(t, err) -// return func() { -// assert.Nil(t, os.Remove(name)) -// } -//} +func write(t *testing.T, name, file string) func() { + err := os.WriteFile(name, []byte(file), 0770) + assert.Nil(t, err) + return func() { + assert.Nil(t, os.Remove(name)) + } +} diff --git a/cmd/debug_test.go b/cmd/debug_test.go new file mode 100644 index 0000000..ac42249 --- /dev/null +++ b/cmd/debug_test.go @@ -0,0 +1,98 @@ +package cmd + +import ( + "runtime" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDebug(t *testing.T) { + + // app run will return an error if the hostsfile does not exist + t.Run("hostsfile that doesn't exist", func(t *testing.T) { + args, _ := setup("-f", "no-existy", "debug") + err := App.Run(args) + assert.NotEmpty(t, err) + if runtime.GOOS == "windows" { + assert.Equal(t, "open no-existy: The system cannot find the file specified.", err.Error()) + } else { + assert.Equal(t, "open no-existy: no such file or directory", err.Error()) + } + }) + + tests := map[string]struct { + input string + expected string + }{ + "hostsfile has only 1 line": { + input: `127.0.0.1 localhost +`, + expected: `hosts file path: test-debug ++-----------+-------+ +| TYPE | COUNT | ++-----------+-------+ +| lines | 1 | +| entries | 1 | +| comments | 0 | +| empty | 0 | +| malformed | 0 | ++-----------+-------+ +`, + }, + "hotsfile only has 1 malformed line": { + input: `127.x.x.x localhost +`, + expected: `hosts file path: test-debug ++-----------+-------+ +| TYPE | COUNT | ++-----------+-------+ +| lines | 1 | +| entries | 1 | +| comments | 0 | +| empty | 0 | +| malformed | 1 | ++-----------+-------+ +`, + }, + "hotsfile only has 1 empty line": { + input: ` +`, + expected: `hosts file path: test-debug ++-----------+-------+ +| TYPE | COUNT | ++-----------+-------+ +| lines | 1 | +| entries | 0 | +| comments | 0 | +| empty | 1 | +| malformed | 0 | ++-----------+-------+ +`, + }, + "hotsfile only has 1 comment line": { + input: `# comment +`, + expected: `hosts file path: test-debug ++-----------+-------+ +| TYPE | COUNT | ++-----------+-------+ +| lines | 1 | +| entries | 0 | +| comments | 1 | +| empty | 0 | +| malformed | 0 | ++-----------+-------+ +`, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + defer read(t, "test-debug", test.input)() + args, out := setup("-f", "test-debug", "debug") + assert.Nil(t, App.Run(args)) + assert.Equal(t, test.expected, out.String()) + }) + } +} diff --git a/cmd/list_test.go b/cmd/list_test.go index 97b9e9e..7bc3983 100644 --- a/cmd/list_test.go +++ b/cmd/list_test.go @@ -8,22 +8,60 @@ import ( ) func TestList(t *testing.T) { - args, _ := setup("-f", "no-existy", "list") - err := App.Run(args) - assert.NotEmpty(t, err) - if runtime.GOOS == "windows" { - assert.Equal(t, "open no-existy: The system cannot find the file specified.", err.Error()) - } else { - assert.Equal(t, "open no-existy: no such file or directory", err.Error()) - } + // app run will return an error if the hostsfile does not exist + t.Run("hostsfile that doesn't exist", func(t *testing.T) { + args, _ := setup("-f", "no-existy", "list") + err := App.Run(args) + assert.NotEmpty(t, err) + if runtime.GOOS == "windows" { + assert.Equal(t, "open no-existy: The system cannot find the file specified.", err.Error()) + } else { + assert.Equal(t, "open no-existy: no such file or directory", err.Error()) + } + }) + + // this is really a noop but future proofs us a bit + t.Run("hostsfile that is write accessible", func(t *testing.T) { + defer write(t, "test-list", "127.0.0.1 localhost")() + args, out := setup("-f", "test-list", "list") + assert.Empty(t, App.Run(args)) + assert.Equal(t, "127.0.0.1 localhost"+"\n", out.String()) + }) - file := "list" - content := "127.0.0.1 localhost" + // test reading the system hostsfile + t.Run("read the system hostsfile", func(t *testing.T) { + args, out := setup("list") + assert.Empty(t, App.Run(args)) + assert.NotEmpty(t, out) + }) - cleanup := read(t, file, content) - defer cleanup() + tests := map[string]struct { + input string + expected string + }{ + "hostsfile that is readonly": { + input: `127.0.0.1 localhost +`, + expected: `127.0.0.1 localhost +`, + }, + "malformed comment added to row": { + input: `127.x.x.x localhost +127.x.x.x localhost # comment +`, + expected: `127.x.x.x localhost # <<< Malformed! +127.x.x.x localhost # comment <<< Malformed! +`, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + defer read(t, "list-test", test.input)() + args, out := setup("-f", "list-test", "list") + assert.Empty(t, App.Run(args)) + assert.Equal(t, test.expected, out.String()) + }) + } - args, out := setup("-f", file, "list") - assert.Empty(t, App.Run(args)) - assert.Equal(t, content+"\n", out.String()) }