Skip to content

Commit f40018c

Browse files
committed
Added more test-cases
For the commands that write to STDIO we've introduced a level of indirection using a handle for writing to. We then look for that output when running tests - mocking the writes to a temporary buffer
1 parent a10e3fb commit f40018c

8 files changed

+240
-15
lines changed

config_cmd.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ delay | The amount of time to sleep between retried HTTP-fetches.
101101
// Execute is invoked if the user specifies `add` as the subcommand.
102102
func (a *configCmd) Execute(args []string) int {
103103

104-
fmt.Printf("This command only exists to show help, when executed as")
105-
fmt.Printf("\n")
106-
fmt.Printf("rss2email help config")
107-
fmt.Printf("\n")
104+
fmt.Fprintf(out, "This command only exists to show help, when executed as:")
105+
fmt.Fprintf(out, "\n")
106+
fmt.Fprintf(out, "rss2email help config")
107+
fmt.Fprintf(out, "\n")
108108

109109
// All done, with no errors.
110110
return 0

config_cmd_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"strings"
6+
"testing"
7+
)
8+
9+
func TestConfig(t *testing.T) {
10+
11+
bak := out
12+
out = new(bytes.Buffer)
13+
defer func() { out = bak }()
14+
15+
s := configCmd{}
16+
17+
//
18+
// Call the handler.
19+
//
20+
s.Execute([]string{})
21+
22+
//
23+
// Look for some lines in the output
24+
//
25+
expected := []string{
26+
"only exists to show help",
27+
"rss2email help config",
28+
}
29+
30+
// The text written to stdout
31+
output := out.(*bytes.Buffer).String()
32+
33+
for _, txt := range expected {
34+
if !strings.Contains(output, txt) {
35+
t.Fatalf("Failed to find expected output")
36+
}
37+
}
38+
}

export_cmd.go

+16-8
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
package main
66

77
import (
8+
"flag"
89
"fmt"
9-
"os"
1010
"text/template"
1111

1212
"github.com/skx/rss2email/configfile"
@@ -18,6 +18,9 @@ type exportCmd struct {
1818

1919
// We embed the NoFlags option, because we accept no command-line flags.
2020
subcommands.NoFlags
21+
22+
// Configuration file, used for testing
23+
config *configfile.ConfigFile
2124
}
2225

2326
// Info is part of the subcommand-API
@@ -37,6 +40,14 @@ Example:
3740
`
3841
}
3942

43+
// Arguments handles argument-flags we might have.
44+
//
45+
// In our case we use this as a hook to setup our configuration-file,
46+
// which allows testing.
47+
func (e *exportCmd) Arguments(flags *flag.FlagSet) {
48+
e.config = configfile.New()
49+
}
50+
4051
// Execute is invoked if the user specifies `add` as the subcommand.
4152
func (e *exportCmd) Execute(args []string) int {
4253

@@ -51,14 +62,11 @@ func (e *exportCmd) Execute(args []string) int {
5162
}
5263
data := TemplateData{}
5364

54-
// Get the configuration-file
55-
conf := configfile.New()
56-
57-
// Upgrade it if necessary
58-
conf.Upgrade()
65+
// Upgrade our configuration file if necessary
66+
e.config.Upgrade()
5967

6068
// Now do the parsing
61-
entries, err := conf.Parse()
69+
entries, err := e.config.Parse()
6270
if err != nil {
6371
fmt.Printf("Error with config-file: %s\n", err.Error())
6472
return 1
@@ -83,7 +91,7 @@ func (e *exportCmd) Execute(args []string) int {
8391
`
8492
// Compile the template and write to STDOUT
8593
t := template.Must(template.New("tmpl").Parse(tmpl))
86-
err = t.Execute(os.Stdout, data)
94+
err = t.Execute(out, data)
8795
if err != nil {
8896
fmt.Printf("error rendering template: %s\n", err.Error())
8997
return 1

export_cmd_test.go

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"io/ioutil"
6+
"os"
7+
"strings"
8+
"testing"
9+
10+
"github.com/skx/rss2email/configfile"
11+
)
12+
13+
func TestExport(t *testing.T) {
14+
15+
// Replace the STDIO handle
16+
bak := out
17+
out = new(bytes.Buffer)
18+
defer func() { out = bak }()
19+
20+
// Create a simple configuration file
21+
content := `# Comment here
22+
https://example.org/
23+
https://example.net/
24+
- foo: bar
25+
`
26+
data := []byte(content)
27+
tmpfile, err := ioutil.TempFile("", "example")
28+
if err != nil {
29+
t.Fatalf("Error creating temporary file")
30+
}
31+
32+
if _, err := tmpfile.Write(data); err != nil {
33+
t.Fatalf("Error writing to config file")
34+
}
35+
if err := tmpfile.Close(); err != nil {
36+
t.Fatalf("Error creating temporary file")
37+
}
38+
39+
// Create an instance of the command, and setup the config file
40+
ex := exportCmd{}
41+
ex.Arguments(nil)
42+
config := configfile.NewWithPath(tmpfile.Name())
43+
ex.config = config
44+
45+
// Run the export
46+
ex.Execute([]string{})
47+
48+
//
49+
// Look for some lines in the output
50+
//
51+
expected := []string{
52+
"Feed Export",
53+
"xmlUrl=\"https://example.org/\"",
54+
"</opml>",
55+
}
56+
57+
// The text written to stdout
58+
output := out.(*bytes.Buffer).String()
59+
60+
for _, txt := range expected {
61+
if !strings.Contains(output, txt) {
62+
t.Fatalf("Failed to find expected output")
63+
}
64+
}
65+
66+
// Cleanup
67+
os.Remove(tmpfile.Name())
68+
}

list_default_template_cmd.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,6 @@ func (l *listDefaultTemplateCmd) Execute(args []string) int {
5454
os.Exit(1)
5555
}
5656

57-
fmt.Printf("%s\n", string(content))
57+
fmt.Fprintf(out, "%s\n", string(content))
5858
return 0
5959
}

list_default_template_cmd_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"flag"
6+
"strings"
7+
"testing"
8+
)
9+
10+
func TestDefaultTemplate(t *testing.T) {
11+
12+
bak := out
13+
out = new(bytes.Buffer)
14+
defer func() { out = bak }()
15+
16+
s := listDefaultTemplateCmd{}
17+
18+
//
19+
// Call the Arguments function for coverage.
20+
//
21+
flags := flag.NewFlagSet("test", flag.ContinueOnError)
22+
s.Arguments(flags)
23+
24+
//
25+
// Call the handler.
26+
//
27+
s.Execute([]string{})
28+
29+
//
30+
// Look for some lines in the output
31+
//
32+
expected := []string{
33+
"X-RSS-Link: {{.Link}}",
34+
"Content-Type: multipart/alternative;",
35+
"the default template which is used by default to generate emails",
36+
}
37+
38+
// The text written to stdout
39+
output := out.(*bytes.Buffer).String()
40+
41+
for _, txt := range expected {
42+
if !strings.Contains(output, txt) {
43+
t.Fatalf("Failed to find expected output")
44+
}
45+
}
46+
}

version_cmd.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@ package main
77
import (
88
"flag"
99
"fmt"
10+
"io"
11+
"os"
1012
"runtime"
1113
)
1214

15+
//
16+
// modified during testing
17+
//
18+
var out io.Writer = os.Stdout
19+
1320
var (
1421
version = "unreleased"
1522
)
@@ -35,9 +42,9 @@ func (v *versionCmd) Arguments(f *flag.FlagSet) {
3542
// Show the version - using the "out"-writer.
3643
//
3744
func showVersion(verbose bool) {
38-
fmt.Printf("%s\n", version)
45+
fmt.Fprintf(out, "%s\n", version)
3946
if verbose {
40-
fmt.Printf("Built with %s\n", runtime.Version())
47+
fmt.Fprintf(out, "Built with %s\n", runtime.Version())
4148
}
4249
}
4350

version_cmd_test.go

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"flag"
6+
"runtime"
7+
"testing"
8+
)
9+
10+
func TestVersion(t *testing.T) {
11+
bak := out
12+
out = new(bytes.Buffer)
13+
defer func() { out = bak }()
14+
15+
//
16+
// Expected
17+
//
18+
expected := "unreleased\n"
19+
20+
s := versionCmd{}
21+
22+
//
23+
// Call the Arguments function for coverage.
24+
//
25+
flags := flag.NewFlagSet("test", flag.ContinueOnError)
26+
s.Arguments(flags)
27+
28+
//
29+
// Call the handler.
30+
//
31+
s.Execute([]string{})
32+
33+
if out.(*bytes.Buffer).String() != expected {
34+
t.Errorf("Expected '%s' received '%s'", expected, out)
35+
}
36+
}
37+
38+
func TestVersionVerbose(t *testing.T) {
39+
bak := out
40+
out = new(bytes.Buffer)
41+
defer func() { out = bak }()
42+
43+
//
44+
// Expected
45+
//
46+
expected := "unreleased\nBuilt with " + runtime.Version() + "\n"
47+
48+
s := versionCmd{verbose: true}
49+
50+
//
51+
// Call the handler.
52+
//
53+
s.Execute([]string{})
54+
55+
if out.(*bytes.Buffer).String() != expected {
56+
t.Errorf("Expected '%s' received '%s'", expected, out)
57+
}
58+
}

0 commit comments

Comments
 (0)