Practical Go. Amit Saha

Читать онлайн.
Название Practical Go
Автор произведения Amit Saha
Жанр Программы
Серия
Издательство Программы
Год выпуска 0
isbn 9781119773832



Скачать книгу

a specified number of times. Usage of greeter: <options> [name] Options: -n int Number of times to greet

      Two points are worth noting here:

       The error is displayed only once now instead of being displayed twice.

       Our custom usage is displayed instead of the default.

      Try a few input combinations before moving on to updating the unit tests.

      We are going to finish off the chapter by updating the unit tests for the functions that we modified. Consider the parseArgs() function first. We will define a new anonymous struct for the test cases:

      tests := []struct { args []string config output string err error }{..} The fields are as follows:

       args: A slice of strings that contains the command-line arguments to parse.

       config: An embedded field representing the expected config object value.

       output: A string that will store the expected standard output.

       err: An error value that will store the expected error.

      Next, we define a slice of test cases representing the various test cases. The first one is as follows:

      The preceding test cases test the behavior when the program is run with the -h argument. In other words, it prints the usage message. Then we have two test configs testing the behavior of the parseArgs() function for different values specified in the -n option:

       { args: []string{"-n", "10"}, err: nil, config: config{numTimes: 10}, }, { args: []string{"-n", "abc"}, err: errors.New("invalid value \"abc\" for flag -n: parse error"), config: config{numTimes: 0}, },

      The final two test configs test the name specified as a positional argument:

       { args: []string{"-n", "1", "John Doe"}, err: nil, config: config{numTimes: 1, name: "John Doe"}, }, { args: []string{"-n", "1", "John", "Doe"}, err: errors.New("More than one positional argument specified"), config: config{numTimes: 1}, },

      Save Listing 1.8 into a new file, parse_args_test.go, in the same directory that you used for Listing 1.7. The test for the validateArgs() function is the same as Listing 1.3, and you can find it in the validate_args_test.go file in the flag-improvements subdirectory of the book's code.

      The unit test for the runCmd() function remains the same as that of Listing 1.4, except for a new test configuration where the name is specified by the user via a positional argument. The tests slice is defined as follows:

      Save the Listing 1.9 code to a new file, run_cmd_test.go, in the same directory as Listing 1.8.

      Now, run all of the tests:

      $ go test -v === RUN TestParseArgs --- PASS: TestParseArgs (0.00s) === RUN TestRunCmd --- PASS: TestRunCmd (0.00s) === RUN TestValidateArgs --- PASS: TestValidateArgs (0.00s) PASS ok github.com/practicalgo/code/chap1/flag-improvements 0.376s

      We started off the chapter implementing a basic command-line interface by directly parsing the command-line arguments. You then saw how you can make use of the flag package to define a standard command-line interface. Instead of implementing the parsing and validating the arguments ourselves, you learned to use the package's built-in support for user-specified arguments and data type validation. All throughout the chapter, you wrote well-encapsulated functions to make unit testing straightforward.

      In the next chapter, you will continue your journey into the flag package by learning to implement command-line applications with sub-commands, introducing robustness into your applications and more.

      In this chapter, you will learn how to use the flag package to implement command-line applications