@@ -2,67 +2,63 @@ package main
22
33import (
44 "bytes"
5- "fmt"
6- "io"
75 "os"
86 "regexp"
97 "testing"
108)
119
12- // Strip ANSI color codes
1310var ansiRegex = regexp .MustCompile (`\x1b\[[0-9;]*m` )
1411
15- func stripANSI (input string ) string {
16- return ansiRegex .ReplaceAllString (input , "" )
17- }
12+ func captureOutput (f func ()) string {
13+ var buf bytes.Buffer
14+ stdout := os .Stdout
15+ r , w , _ := os .Pipe ()
16+ os .Stdout = w
1817
19- func TestMainFunction (t * testing.T ) {
20- version := "v0.7.0"
18+ f ()
2119
22- // Backup the original exit function and stdout/stderr
23- originalExit := exit
24- originalStdout := os .Stdout
25- originalStderr := os .Stderr
26- defer func () {
27- exit = originalExit // Restore exit
28- os .Stdout = originalStdout // Restore stdout
29- os .Stderr = originalStderr // Restore stderr
30- }()
20+ _ = w .Close ()
21+ os .Stdout = stdout
22+ _ , _ = buf .ReadFrom (r )
3123
32- // Replace exit with a function that captures the exit code
33- exitCode := 0
34- exit = func (code int ) { exitCode = code }
24+ return buf .String ()
25+ }
3526
27+ func stripANSI (input string ) string {
28+ return ansiRegex .ReplaceAllString (input , "" )
29+ }
30+
31+ func TestRunCLI (t * testing.T ) {
3632 tests := []struct {
33+ name string
3734 args []string
3835 expectedOutput string
39- expectedExit int
36+ expectedCode int
4037 }{
4138 {
42- args : []string {"pokemons" },
39+ name : "No Arguments" ,
40+ args : []string {},
4341 expectedOutput : "╭──────────────────────────────────────────────────────╮\n " +
44- "│Error! │\n " +
45- "│ 'pokemons' is not a valid command. │\n " +
42+ "│Welcome! This tool displays data related to Pokémon! │\n " +
4643 "│ │\n " +
47- "│Available Commands: │\n " +
44+ "│ USAGE: │\n " +
45+ "│ poke-cli [flag] │\n " +
46+ "│ poke-cli <command> [flag] │\n " +
47+ "│ poke-cli <command> <subcommand> [flag] │\n " +
48+ "│ │\n " +
49+ "│ FLAGS: │\n " +
50+ "│ -h, --help Shows the help menu │\n " +
51+ "│ -l, --latest Prints the latest available │\n " +
52+ "│ version of the program │\n " +
53+ "│ │\n " +
54+ "│ AVAILABLE COMMANDS: │\n " +
4855 "│ pokemon Get details of a specific Pokémon │\n " +
4956 "│ types Get details of a specific typing │\n " +
50- "│ │\n " +
51- "│Also run [poke-cli -h] for more info! │\n " +
5257 "╰──────────────────────────────────────────────────────╯\n " ,
53- expectedExit : 1 ,
54- },
55- {
56- args : []string {"-l" },
57- expectedOutput : fmt .Sprintf ("Latest Docker image version: %s\n Latest release tag: %s\n " , version , version ),
58- expectedExit : 0 ,
59- },
60- {
61- args : []string {"--latest" },
62- expectedOutput : fmt .Sprintf ("Latest Docker image version: %s\n Latest release tag: %s\n " , version , version ),
63- expectedExit : 0 ,
58+ expectedCode : 0 ,
6459 },
6560 {
61+ name : "Help Flag Short" ,
6662 args : []string {"-h" },
6763 expectedOutput : "╭──────────────────────────────────────────────────────╮\n " +
6864 "│Welcome! This tool displays data related to Pokémon! │\n " +
@@ -81,64 +77,59 @@ func TestMainFunction(t *testing.T) {
8177 "│ pokemon Get details of a specific Pokémon │\n " +
8278 "│ types Get details of a specific typing │\n " +
8379 "╰──────────────────────────────────────────────────────╯\n " ,
84- expectedExit : 0 ,
85- },
86- {
87- args : []string {"pokemon" , "kingambit" },
88- expectedOutput : "Your selected Pokémon: Kingambit\n National Pokédex #: 983\n " ,
89- expectedExit : 0 ,
80+ expectedCode : 0 ,
9081 },
9182 {
92- args : []string {"pokemon" , "cradily" , "--types" },
93- expectedOutput : "Your selected Pokémon: Cradily\n National Pokédex #: 346\n ──────\n Typing\n Type 1: rock\n Type 2: grass\n " ,
94- expectedExit : 0 ,
83+ name : "Help Flag Long" ,
84+ args : []string {"--help" },
85+ expectedOutput : "╭──────────────────────────────────────────────────────╮\n " +
86+ "│Welcome! This tool displays data related to Pokémon! │\n " +
87+ "│ │\n " +
88+ "│ USAGE: │\n " +
89+ "│ poke-cli [flag] │\n " +
90+ "│ poke-cli <command> [flag] │\n " +
91+ "│ poke-cli <command> <subcommand> [flag] │\n " +
92+ "│ │\n " +
93+ "│ FLAGS: │\n " +
94+ "│ -h, --help Shows the help menu │\n " +
95+ "│ -l, --latest Prints the latest available │\n " +
96+ "│ version of the program │\n " +
97+ "│ │\n " +
98+ "│ AVAILABLE COMMANDS: │\n " +
99+ "│ pokemon Get details of a specific Pokémon │\n " +
100+ "│ types Get details of a specific typing │\n " +
101+ "╰──────────────────────────────────────────────────────╯\n " ,
102+ expectedCode : 0 ,
95103 },
96104 {
97- args : []string {"pokemon" , "giratina-altered" , "--abilities" },
98- expectedOutput : "Your selected Pokémon: Giratina-Altered\n National Pokédex #: 487\n ─────────\n Abilities\n Ability 1: pressure\n Hidden Ability: telepathy\n " ,
99- expectedExit : 0 ,
105+ name : "Invalid Command" ,
106+ args : []string {"invalid" },
107+ expectedOutput : "Error!" ,
108+ expectedCode : 1 ,
100109 },
101110 {
102- args : []string {"pokemon" , "coPPeraJAH" , "-t" , "-a" },
103- expectedOutput : "Your selected Pokémon: Copperajah\n National Pokédex #: 879\n ──────\n Typing\n Type 1: steel\n ─────────\n Abilities\n Ability 1: sheer-force\n Hidden Ability: heavy-metal\n " ,
104- expectedExit : 0 ,
111+ name : "Latest Flag" ,
112+ args : []string {"-l" },
113+ expectedOutput : "Latest Docker image version: v0.7.1\n Latest release tag: v0.7.1\n " ,
114+ expectedCode : 0 ,
105115 },
106116 }
107117
108- for _ , test := range tests {
109- // Create a pipe to capture output
110- r , w , _ := os .Pipe ()
111- os .Stdout = w
112- os .Stderr = w
113-
114- // Set os.Args for the test case
115- os .Args = append ([]string {"poke-cli" }, test .args ... )
116-
117- // Run the main function
118- main ()
119-
120- // Close the writer and restore stdout and stderr
121- err := w .Close ()
122- if err != nil {
123- t .Fatalf ("Error closing pipe writer: %v" , err )
124- }
125- os .Stdout = originalStdout
126- os .Stderr = originalStderr
127-
128- // Read from the pipe
129- var buf bytes.Buffer
130- if _ , err := io .Copy (& buf , r ); err != nil {
131- t .Errorf ("Error copying output: %v" , err )
132- }
118+ for _ , tt := range tests {
119+ t .Run (tt .name , func (t * testing.T ) {
120+ exit = func (code int ) {}
121+ output := captureOutput (func () {
122+ code := runCLI (tt .args )
123+ if code != tt .expectedCode {
124+ t .Errorf ("Expected exit code %d, got %d" , tt .expectedCode , code )
125+ }
126+ })
133127
134- // Strip ANSI color codes from the actual output
135- actualOutput := stripANSI (buf .String ())
136- if actualOutput != test .expectedOutput {
137- t .Errorf ("Args: %v\n Expected output: %q\n Got: %q\n " , test .args , test .expectedOutput , actualOutput )
138- }
128+ output = stripANSI (output )
139129
140- if exitCode != test .expectedExit {
141- t .Errorf ("Args: %v\n Expected exit code: %d\n Got: %d\n " , test .args , test .expectedExit , exitCode )
142- }
130+ if ! bytes .Contains ([]byte (output ), []byte (tt .expectedOutput )) {
131+ t .Errorf ("Expected output to contain %q, got %q" , tt .expectedOutput , output )
132+ }
133+ })
143134 }
144135}
0 commit comments