text:
package cli

import (
	"bytes"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"reflect"
	"strconv"
	"strings"
	"testing"
	"time"
)

var (
	lastExitCode = 0
	fakeOsExiter = func(rc int) {
		lastExitCode = rc
	}
	fakeErrWriter = &bytes.Buffer{}
)

func init() {
	OsExiter = fakeOsExiter
	ErrWriter = fakeErrWriter
}

type opCounts struct {
	Total, ShellComplete, OnUsageError, Before, CommandNotFound, Action, After, SubCommand int
}

func ExampleApp_Run() {
	// set args for examples sake
	os.Args = []string{"greet", "--name", "Jeremy"}

	app := &App{
		Name: "greet",
		Flags: []Flag{
			&StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
		},
		Action: func(c *Context) error {
			fmt.Printf("Hello %v\n", c.String("name"))
			return nil
		},
		UsageText: "app [first_arg] [second_arg]",
		Authors:   []*Author{{Name: "Oliver Allen", Email: "oliver@toyshop.example.com"}},
	}

	app.Run(os.Args)
	// Output:
	// Hello Jeremy
}

func ExampleApp_Run_subcommand() {
	// set args for examples sake
	os.Args = []string{"say", "hi", "english", "--name", "Jeremy"}
	app := &App{
		Name: "say",
		Commands: []*Command{
			{
				Name:        "hello",
				Aliases:     []string{"hi"},
				Usage:       "use it to see a description",
				Description: "This is how we describe hello the function",
				Subcommands: []*Command{
					{
						Name:        "english",
						Aliases:     []string{"en"},
						Usage:       "sends a greeting in english",
						Description: "greets someone in english",
						Flags: []Flag{
							&StringFlag{
								Name:  "name",
								Value: "Bob",
								Usage: "Name of the person to greet",
							},
						},
						Action: func(c *Context) error {
							fmt.Println("Hello,", c.String("name"))
							return nil
						},
					},
				},
			},
		},
	}

	_ = app.Run(os.Args)
	// Output:
	// Hello, Jeremy
}

func ExampleApp_Run_appHelp() {
	// set args for examples sake
	os.Args = []string{"greet", "help"}

	app := &App{
		Name:        "greet",
		Version:     "0.1.0",
		Description: "This is how we describe greet the app",
		Authors: []*Author{
			{Name: "Harrison", Email: "harrison@lolwut.com"},
			{Name: "Oliver Allen", Email: "oliver@toyshop.com"},
		},
		Flags: []Flag{
			&StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
		},
		Commands: []*Command{
			{
				Name:        "describeit",
				Aliases:     []string{"d"},
				Usage:       "use it to see a description",
				Description: "This is how we describe describeit the function",
				Action: func(c *Context) error {
					fmt.Printf("i like to describe things")
					return nil
				},
			},
		},
	}
	_ = app.Run(os.Args)
	// Output:
	// NAME:
	//    greet - A new cli application
	//
	// USAGE:
	//    greet [global options] command [command options] [arguments...]
	//
	// VERSION:
	//    0.1.0
	//
	// DESCRIPTION:
	//    This is how we describe greet the app
	//
	// AUTHORS:
	//    Harrison <harrison@lolwut.com>
	//    Oliver Allen <oliver@toyshop.com>
	//
	// COMMANDS:
	//    describeit, d  use it to see a description
	//    help, h        Shows a list of commands or help for one command
	//
	// GLOBAL OPTIONS:
	//    --name value   a name to say (default: "bob")
	//    --help, -h     show help (default: false)
	//    --version, -v  print the version (default: false)
}

func ExampleApp_Run_commandHelp() {
	// set args for examples sake
	os.Args = []string{"greet", "h", "describeit"}

	app := &App{
		Name: "greet",
		Flags: []Flag{
			&StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
		},
		Commands: []*Command{
			{
				Name:        "describeit",
				Aliases:     []string{"d"},
				Usage:       "use it to see a description",
				Description: "This is how we describe describeit the function",
				Action: func(c *Context) error {
					fmt.Printf("i like to describe things")
					return nil
				},
			},
		},
	}
	_ = app.Run(os.Args)
	// Output:
	// NAME:
	//    greet describeit - use it to see a description
	//
	// USAGE:
	//    greet describeit [command options] [arguments...]
	//
	// DESCRIPTION:
	//    This is how we describe describeit the function
	//
	// OPTIONS:
	//    --help, -h  show help (default: false)
}

func ExampleApp_Run_noAction() {
	app := App{}
	app.Name = "greet"
	_ = app.Run([]string{"greet"})
	// Output:
	// NAME:
	//    greet - A new cli application
	//
	// USAGE:
	//    greet [global options] command [command options] [arguments...]
	//
	// COMMANDS:
	//    help, h  Shows a list of commands or help for one command
	//
	// GLOBAL OPTIONS:
	//    --help, -h  show help (default: false)
}

func ExampleApp_Run_subcommandNoAction() {
	app := &App{
		Name: "greet",
		Commands: []*Command{
			{
				Name:        "describeit",
				Aliases:     []string{"d"},
				Usage:       "use it to see a description",
				Description: "This is how we describe describeit the function",
			},
		},
	}
	_ = app.Run([]string{"greet", "describeit"})
	// Output:
	// NAME:
	//    greet describeit - use it to see a description
	//
	// USAGE:
	//    greet describeit [command options] [arguments...]
	//
	// DESCRIPTION:
	//    This is how we describe describeit the function
	//
	// OPTIONS:
	//    --help, -h  show help (default: false)

}

func ExampleApp_Run_bashComplete_withShortFlag() {
	os.Setenv("SHELL", "bash")
	os.Args = []string{"greet", "-", "--generate-bash-completion"}

	app := NewApp()
	app.Name = "greet"
	app.EnableBashCompletion = true
	app.Flags = []Flag{
		&IntFlag{
			Name:    "other",
			Aliases: []string{"o"},
		},
		&StringFlag{
			Name:    "xyz",
			Aliases: []string{"x"},
		},
	}

	_ = app.Run(os.Args)
	// Output:
	// --other
	// -o
	// --xyz
	// -x
	// --help
	// -h
}

func ExampleApp_Run_bashComplete_withLongFlag() {
	os.Setenv("SHELL", "bash")
	os.Args = []string{"greet", "--s", "--generate-bash-completion"}

	app := NewApp()
	app.Name = "greet"
	app.EnableBashCompletion = true
	app.Flags = []Flag{
		&IntFlag{
			Name:    "other",
			Aliases: []string{"o"},
		},
		&StringFlag{
			Name:    "xyz",
			Aliases: []string{"x"},
		},
		&StringFlag{
			Name: "some-flag,s",
		},
		&StringFlag{
			Name: "similar-flag",
		},
	}

	_ = app.Run(os.Args)
	// Output:
	// --some-flag
	// --similar-flag
}
func ExampleApp_Run_bashComplete_withMultipleLongFlag() {
	os.Setenv("SHELL", "bash")
	os.Args = []string{"greet", "--st", "--generate-bash-completion"}

	app := NewApp()
	app.Name = "greet"
	app.EnableBashCompletion = true
	app.Flags = []Flag{
		&IntFlag{
			Name:    "int-flag",
			Aliases: []string{"i"},
		},
		&StringFlag{
			Name:    "string",
			Aliases: []string{"s"},
		},
		&StringFlag{
			Name: "string-flag-2",
		},
		&StringFlag{
			Name: "similar-flag",
		},
		&StringFlag{
			Name: "some-flag",
		},
	}

	_ = app.Run(os.Args)
	// Output:
	// --string
	// --string-flag-2
}

func ExampleApp_Run_bashComplete() {
	os.Setenv("SHELL", "bash")
	os.Args = []string{"greet", "--generate-bash-completion"}

	app := &App{
		Name:                 "greet",
		EnableBashCompletion: true,
		Commands: []*Command{
			{
				Name:        "describeit",
				Aliases:     []string{"d"},
				Usage:       "use it to see a description",
				Description: "This is how we describe describeit the function",
				Action: func(c *Context) error {
					fmt.Printf("i like to describe things")
					return nil
				},
			}, {
				Name:        "next",
				Usage:       "next example",
				Description: "more stuff to see when generating shell completion",
				Action: func(c *Context) error {
					fmt.Printf("the next example")
					return nil
				},
			},
		},
	}

	_ = app.Run(os.Args)
	// Output:
	// describeit
	// d
	// next
	// help
	// h
}

func ExampleApp_Run_zshComplete() {
	// set args for examples sake
	os.Args = []string{"greet", "--generate-bash-completion"}
	_ = os.Setenv("SHELL", "/usr/bin/zsh")

	app := NewApp()
	app.Name = "greet"
	app.EnableBashCompletion = true
	app.Commands = []*Command{
		{
			Name:        "describeit",
			Aliases:     []string{"d"},
			Usage:       "use it to see a description",
			Description: "This is how we describe describeit the function",
			Action: func(c *Context) error {
				fmt.Printf("i like to describe things")
				return nil
			},
		}, {
			Name:        "next",
			Usage:       "next example",
			Description: "more stuff to see when generating bash completion",
			Action: func(c *Context) error {
				fmt.Printf("the next example")
				return nil
			},
		},
	}

	_ = app.Run(os.Args)
	// Output:
	// describeit:use it to see a description
	// d:use it to see a description
	// next:next example
	// help:Shows a list of commands or help for one command
	// h:Shows a list of commands or help for one command
}

func ExampleApp_Run_sliceValues() {
	// set args for examples sake
	os.Args = []string{"multi_values",
		"--stringSclice", "parsed1,parsed2", "--stringSclice", "parsed3,parsed4",
		"--float64Sclice", "13.3,14.4", "--float64Sclice", "15.5,16.6",
		"--int64Sclice", "13,14", "--int64Sclice", "15,16",
		"--intSclice", "13,14", "--intSclice", "15,16",
	}
	app := NewApp()
	app.Name = "multi_values"
	app.Flags = []Flag{
		&StringSliceFlag{Name: "stringSclice"},
		&Float64SliceFlag{Name: "float64Sclice"},
		&Int64SliceFlag{Name: "int64Sclice"},
		&IntSliceFlag{Name: "intSclice"},
	}
	app.Action = func(ctx *Context) error {
		for i, v := range ctx.FlagNames() {
			fmt.Printf("%d-%s %#v\n", i, v, ctx.Value(v))
		}
		err := ctx.Err()
		fmt.Println("error:", err)
		return err
	}

	_ = app.Run(os.Args)
	// Output:
	// 0-float64Sclice cli.Float64Slice{slice:[]float64{13.3, 14.4, 15.5, 16.6}, hasBeenSet:true}
	// 1-int64Sclice cli.Int64Slice{slice:[]int64{13, 14, 15, 16}, hasBeenSet:true}
	// 2-intSclice cli.IntSlice{slice:[]int{13, 14, 15, 16}, hasBeenSet:true}
	// 3-stringSclice cli.StringSlice{slice:[]string{"parsed1", "parsed2", "parsed3", "parsed4"}, hasBeenSet:true}
	// error: <nil>
}

func TestApp_Run(t *testing.T) {
	s := ""

	app := &App{
		Action: func(c *Context) error {
			s = s + c.Args().First()
			return nil
		},
	}

	err := app.Run([]string{"command", "foo"})
	expect(t, err, nil)
	err = app.Run([]string{"command", "bar"})
	expect(t, err, nil)
	expect(t, s, "foobar")
}

var commandAppTests = []struct {
	name     string
	expected bool
}{
	{"foobar", true},
	{"batbaz", true},
	{"b", true},
	{"f", true},
	{"bat", false},
	{"nothing", false},
}

func TestApp_Command(t *testing.T) {
	app := &App{
		Commands: []*Command{
			{Name: "foobar", Aliases: []string{"f"}},
			{Name: "batbaz", Aliases: []string{"b"}},
		},
	}

	for _, test := range commandAppTests {
		expect(t, app.Command(test.name) != nil, test.expected)
	}
}

var defaultCommandAppTests = []struct {
	cmdName    string
	defaultCmd string
	expected   bool
}{
	{"foobar", "foobar", true},
	{"batbaz", "foobar", true},
	{"b", "", true},
	{"f", "", true},
	{"", "foobar", true},
	{"", "", true},
	{" ", "", false},
	{"bat", "batbaz", false},
	{"nothing", "batbaz", false},
	{"nothing", "", false},
}

func TestApp_RunDefaultCommand(t *testing.T) {
	for _, test := range defaultCommandAppTests {
		testTitle := fmt.Sprintf("command=%[1]s-default=%[2]s", test.cmdName, test.defaultCmd)
		t.Run(testTitle, func(t *testing.T) {
			app := &App{
				DefaultCommand: test.defaultCmd,
				Commands: []*Command{
					{Name: "foobar", Aliases: []string{"f"}},
					{Name: "batbaz", Aliases: []string{"b"}},
				},
			}

			err := app.Run([]string{"c", test.cmdName})
			expect(t, err == nil, test.expected)
		})
	}
}

var defaultCommandSubCmdAppTests = []struct {
	cmdName    string
	subCmd     string
	defaultCmd string
	expected   bool
}{
	{"foobar", "", "foobar", true},
	{"foobar", "carly", "foobar", true},
	{"batbaz", "", "foobar", true},
	{"b", "", "", true},
	{"f", "", "", true},
	{"", "", "foobar", true},
	{"", "", "", true},
	{"", "jimbob", "foobar", true},
	{"", "j", "foobar", true},
	{"", "carly", "foobar", true},
	{"", "jimmers", "foobar", true},
	{"", "jimmers", "", true},
	{" ", "jimmers", "foobar", false},
	{"", "", "", true},
	{" ", "", "", false},
	{" ", "j", "", false},
	{"bat", "", "batbaz", false},
	{"nothing", "", "batbaz", false},
	{"nothing", "", "", false},
	{"nothing", "j", "batbaz", false},
	{"nothing", "carly", "", false},
}

func TestApp_RunDefaultCommandWithSubCommand(t *testing.T) {
	for _, test := range defaultCommandSubCmdAppTests {
		testTitle := fmt.Sprintf("command=%[1]s-subcmd=%[2]s-default=%[3]s", test.cmdName, test.subCmd, test.defaultCmd)
		t.Run(testTitle, func(t *testing.T) {
			app := &App{
				DefaultCommand: test.defaultCmd,
				Commands: []*Command{
					{
						Name:    "foobar",
						Aliases: []string{"f"},
						Subcommands: []*Command{
							{Name: "jimbob", Aliases: []string{"j"}},
							{Name: "carly"},
						},
					},
					{Name: "batbaz", Aliases: []string{"b"}},
				},
			}

			err := app.Run([]string{"c", test.cmdName, test.subCmd})
			expect(t, err == nil, test.expected)
		})
	}
}

var defaultCommandFlagAppTests = []struct {
	cmdName    string
	flag       string
	defaultCmd string
	expected   bool
}{
	{"foobar", "", "foobar", true},
	{"foobar", "-c derp", "foobar", true},
	{"batbaz", "", "foobar", true},
	{"b", "", "", true},
	{"f", "", "", true},
	{"", "", "foobar", true},
	{"", "", "", true},
	{"", "-j", "foobar", true},
	{"", "-j", "foobar", true},
	{"", "-c derp", "foobar", true},
	{"", "--carly=derp", "foobar", true},
	{"", "-j", "foobar", true},
	{"", "-j", "", true},
	{" ", "-j", "foobar", false},
	{"", "", "", true},
	{" ", "", "", false},
	{" ", "-j", "", false},
	{"bat", "", "batbaz", false},
	{"nothing", "", "batbaz", false},
	{"nothing", "", "", false},
	{"nothing", "--jimbob", "batbaz", false},
	{"nothing", "--carly", "", false},
}

func TestApp_RunDefaultCommandWithFlags(t *testing.T) {
	for _, test := range defaultCommandFlagAppTests {
		testTitle := fmt.Sprintf("command=%[1]s-flag=%[2]s-default=%[3]s", test.cmdName, test.flag, test.defaultCmd)
		t.Run(testTitle, func(t *testing.T) {
			app := &App{
				DefaultCommand: test.defaultCmd,
				Flags: []Flag{
					&StringFlag{
						Name:     "carly",
						Aliases:  []string{"c"},
						Required: false,
					},
					&BoolFlag{
						Name:     "jimbob",
						Aliases:  []string{"j"},
						Required: false,
						Value:    true,
					},
				},
				Commands: []*Command{
					{
						Name:    "foobar",
						Aliases: []string{"f"},
					},
					{Name: "batbaz", Aliases: []string{"b"}},
				},
			}

			appArgs := []string{"c"}

			if test.flag != "" {
				flags := strings.Split(test.flag, " ")
				if len(flags) > 1 {
					appArgs = append(appArgs, flags...)
				}

				flags = strings.Split(test.flag, "=")
				if len(flags) > 1 {
					appArgs = append(appArgs, flags...)
				}
			}

			appArgs = append(appArgs, test.cmdName)

			err := app.Run(appArgs)
			expect(t, err == nil, test.expected)
		})
	}
}

func TestApp_FlagsFromExtPackage(t *testing.T) {

	var someint int
	flag.IntVar(&someint, "epflag", 2, "ext package flag usage")

	// Based on source code we can reset the global flag parsing this way
	defer func() {
		flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
	}()

	a := &App{
		AllowExtFlags: true,
		Flags: []Flag{
			&StringFlag{
				Name:     "carly",
				Aliases:  []string{"c"},
				Required: false,
			},
			&BoolFlag{
				Name:     "jimbob",
				Aliases:  []string{"j"},
				Required: false,
				Value:    true,
			},
		},
	}

	err := a.Run([]string{"foo", "-c", "cly", "--epflag", "10"})
	if err != nil {
		t.Error(err)
	}

	if someint != 10 {
		t.Errorf("Expected 10 got %d for someint", someint)
	}

	a = &App{
		Flags: []Flag{
			&StringFlag{
				Name:     "carly",
				Aliases:  []string{"c"},
				Required: false,
			},
			&BoolFlag{
				Name:     "jimbob",
				Aliases:  []string{"j"},
				Required: false,
				Value:    true,
			},
		},
	}

	// this should return an error since epflag shouldnt be registered
	err = a.Run([]string{"foo", "-c", "cly", "--epflag", "10"})
	if err == nil {
		t.Error("Expected error")
	}
}

func TestApp_Setup_defaultsReader(t *testing.T) {
	app := &App{}
	app.Setup()
	expect(t, app.Reader, os.Stdin)
}

func TestApp_Setup_defaultsWriter(t *testing.T) {
	app := &App{}
	app.Setup()
	expect(t, app.Writer, os.Stdout)
}

func TestApp_RunAsSubcommandParseFlags(t *testing.T) {
	var cCtx *Context

	a := &App{
		Commands: []*Command{
			{
				Name: "foo",
				Action: func(c *Context) error {
					cCtx = c
					return nil
				},
				Flags: []Flag{
					&StringFlag{
						Name:  "lang",
						Value: "english",
						Usage: "language for the greeting",
					},
				},
				Before: func(_ *Context) error { return nil },
			},
		},
	}
	_ = a.Run([]string{"", "foo", "--lang", "spanish", "abcd"})

	expect(t, cCtx.Args().Get(0), "abcd")
	expect(t, cCtx.String("lang"), "spanish")
}

func TestApp_CommandWithFlagBeforeTerminator(t *testing.T) {
	var parsedOption string
	var args Args

	app := &App{
		Commands: []*Command{
			{
				Name: "cmd",
				Flags: []Flag{
					&StringFlag{Name: "option", Value: "", Usage: "some option"},
				},
				Action: func(c *Context) error {
					parsedOption = c.String("option")
					args = c.Args()
					return nil
				},
			},
		},
	}

	_ = app.Run([]string{"", "cmd", "--option", "my-option", "my-arg", "--", "--notARealFlag"})

	expect(t, parsedOption, "my-option")
	expect(t, args.Get(0), "my-arg")
	expect(t, args.Get(1), "--")
	expect(t, args.Get(2), "--notARealFlag")
}

func TestApp_CommandWithDash(t *testing.T) {
	var args Args

	app := &App{
		Commands: []*Command{
			{
				Name: "cmd",
				Action: func(c *Context) error {
					args = c.Args()
					return nil
				},
			},
		},
	}

	_ = app.Run([]string{"", "cmd", "my-arg", "-"})

	expect(t, args.Get(0), "my-arg")
	expect(t, args.Get(1), "-")
}

func TestApp_CommandWithNoFlagBeforeTerminator(t *testing.T) {
	var args Args

	app := &App{
		Commands: []*Command{
			{
				Name: "cmd",
				Action: func(c *Context) error {
					args = c.Args()
					return nil
				},
			},
		},
	}

	_ = app.Run([]string{"", "cmd", "my-arg", "--", "notAFlagAtAll"})

	expect(t, args.Get(0), "my-arg")
	expect(t, args.Get(1), "--")
	expect(t, args.Get(2), "notAFlagAtAll")
}

func TestApp_SkipFlagParsing(t *testing.T) {
	var args Args

	app := &App{
		SkipFlagParsing: true,
		Action: func(c *Context) error {
			args = c.Args()
			return nil
		},
	}

	_ = app.Run([]string{"", "--", "my-arg", "notAFlagAtAll"})

	expect(t, args.Get(0), "--")
	expect(t, args.Get(1), "my-arg")
	expect(t, args.Get(2), "notAFlagAtAll")
}

func TestApp_VisibleCommands(t *testing.T) {
	app := &App{
		Commands: []*Command{
			{
				Name:     "frob",
				HelpName: "foo frob",
				Action:   func(_ *Context) error { return nil },
			},
			{
				Name:     "frib",
				HelpName: "foo frib",
				Hidden:   true,
				Action:   func(_ *Context) error { return nil },
			},
		},
	}

	app.Setup()
	expected := []*Command{
		app.Commands[0],
		app.Commands[2], // help
	}
	actual := app.VisibleCommands()
	expect(t, len(expected), len(actual))
	for i, actualCommand := range actual {
		expectedCommand := expected[i]

		if expectedCommand.Action != nil {
			// comparing func addresses is OK!
			expect(t, fmt.Sprintf("%p", expectedCommand.Action), fmt.Sprintf("%p", actualCommand.Action))
		}

		func() {
			// nil out funcs, as they cannot be compared
			// (https://github.com/golang/go/issues/8554)
			expectedAction := expectedCommand.Action
			actualAction := actualCommand.Action
			defer func() {
				expectedCommand.Action = expectedAction
				actualCommand.Action = actualAction
			}()
			expectedCommand.Action = nil
			actualCommand.Action = nil

			if !reflect.DeepEqual(expectedCommand, actualCommand) {
				t.Errorf("expected\n%#v\n!=\n%#v", expectedCommand, actualCommand)
			}
		}()
	}
}

func TestApp_UseShortOptionHandling(t *testing.T) {
	var one, two bool
	var name string
	expected := "expectedName"

	app := newTestApp()
	app.UseShortOptionHandling = true
	app.Flags = []Flag{
		&BoolFlag{Name: "one", Aliases: []string{"o"}},
		&BoolFlag{Name: "two", Aliases: []string{"t"}},
		&StringFlag{Name: "name", Aliases: []string{"n"}},
	}
	app.Action = func(c *Context) error {
		one = c.Bool("one")
		two = c.Bool("two")
		name = c.String("name")
		return nil
	}

	_ = app.Run([]string{"", "-on", expected})
	expect(t, one, true)
	expect(t, two, false)
	expect(t, name, expected)
}

func TestApp_UseShortOptionHandling_missing_value(t *testing.T) {
	app := newTestApp()
	app.UseShortOptionHandling = true
	app.Flags = []Flag{
		&StringFlag{Name: "name", Aliases: []string{"n"}},
	}

	err := app.Run([]string{"", "-n"})
	expect(t, err, errors.New("flag needs an argument: -n"))
}

func TestApp_UseShortOptionHandlingCommand(t *testing.T) {
	var one, two bool
	var name string
	expected := "expectedName"

	app := newTestApp()
	app.UseShortOptionHandling = true
	command := &Command{
		Name: "cmd",
		Flags: []Flag{
			&BoolFlag{Name: "one", Aliases: []string{"o"}},
			&BoolFlag{Name: "two", Aliases: []string{"t"}},
			&StringFlag{Name: "name", Aliases: []string{"n"}},
		},
		Action: func(c *Context) error {
			one = c.Bool("one")
			two = c.Bool("two")
			name = c.String("name")
			return nil
		},
	}
	app.Commands = []*Command{command}

	_ = app.Run([]string{"", "cmd", "-on", expected})
	expect(t, one, true)
	expect(t, two, false)
	expect(t, name, expected)
}

func TestApp_UseShortOptionHandlingCommand_missing_value(t *testing.T) {
	app := newTestApp()
	app.UseShortOptionHandling = true
	command := &Command{
		Name: "cmd",
		Flags: []Flag{
			&StringFlag{Name: "name", Aliases: []string{"n"}},
		},
	}
	app.Commands = []*Command{command}

	err := app.Run([]string{"", "cmd", "-n"})
	expect(t, err, errors.New("flag needs an argument: -n"))
}

func TestApp_UseShortOptionHandlingSubCommand(t *testing.T) {
	var one, two bool
	var name string
	expected := "expectedName"

	app := newTestApp()
	app.UseShortOptionHandling = true
	command := &Command{
		Name: "cmd",
	}
	subCommand := &Command{
		Name: "sub",
		Flags: []Flag{
			&BoolFlag{Name: "one", Aliases: []string{"o"}},
			&BoolFlag{Name: "two", Aliases: []string{"t"}},
			&StringFlag{Name: "name", Aliases: []string{"n"}},
		},
		Action: func(c *Context) error {
			one = c.Bool("one")
			two = c.Bool("two")
			name = c.String("name")
			return nil
		},
	}
	command.Subcommands = []*Command{subCommand}
	app.Commands = []*Command{command}

	err := app.Run([]string{"", "cmd", "sub", "-on", expected})
	expect(t, err, nil)
	expect(t, one, true)
	expect(t, two, false)
	expect(t, name, expected)
}

func TestApp_UseShortOptionHandlingSubCommand_missing_value(t *testing.T) {
	app := newTestApp()
	app.UseShortOptionHandling = true
	command := &Command{
		Name: "cmd",
	}
	subCommand := &Command{
		Name: "sub",
		Flags: []Flag{
			&StringFlag{Name: "name", Aliases: []string{"n"}},
		},
	}
	command.Subcommands = []*Command{subCommand}
	app.Commands = []*Command{command}

	err := app.Run([]string{"", "cmd", "sub", "-n"})
	expect(t, err, errors.New("flag needs an argument: -n"))
}

func TestApp_UseShortOptionAfterSliceFlag(t *testing.T) {
	var one, two bool
	var name string
	var sliceValDest StringSlice
	var sliceVal []string
	expected := "expectedName"

	app := newTestApp()
	app.UseShortOptionHandling = true
	app.Flags = []Flag{
		&StringSliceFlag{Name: "env", Aliases: []string{"e"}, Destination: &sliceValDest},
		&BoolFlag{Name: "one", Aliases: []string{"o"}},
		&BoolFlag{Name: "two", Aliases: []string{"t"}},
		&StringFlag{Name: "name", Aliases: []string{"n"}},
	}
	app.Action = func(c *Context) error {
		sliceVal = c.StringSlice("env")
		one = c.Bool("one")
		two = c.Bool("two")
		name = c.String("name")
		return nil
	}

	_ = app.Run([]string{"", "-e", "foo", "-on", expected})
	expect(t, sliceVal, []string{"foo"})
	expect(t, sliceValDest.Value(), []string{"foo"})
	expect(t, one, true)
	expect(t, two, false)
	expect(t, name, expected)
}

func TestApp_Float64Flag(t *testing.T) {
	var meters float64

	app := &App{
		Flags: []Flag{
			&Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"},
		},
		Action: func(c *Context) error {
			meters = c.Float64("height")
			return nil
		},
	}

	_ = app.Run([]string{"", "--height", "1.93"})
	expect(t, meters, 1.93)
}

func TestApp_ParseSliceFlags(t *testing.T) {
	var parsedIntSlice []int
	var parsedStringSlice []string

	app := &App{
		Commands: []*Command{
			{
				Name: "cmd",
				Flags: []Flag{
					&IntSliceFlag{Name: "p", Value: NewIntSlice(), Usage: "set one or more ip addr"},
					&StringSliceFlag{Name: "ip", Value: NewStringSlice(), Usage: "set one or more ports to open"},
				},
				Action: func(c *Context) error {
					parsedIntSlice = c.IntSlice("p")
					parsedStringSlice = c.StringSlice("ip")
					return nil
				},
			},
		},
	}

	_ = app.Run([]string{"", "cmd", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"})

	IntsEquals := func(a, b []int) bool {
		if len(a) != len(b) {
			return false
		}
		for i, v := range a {
			if v != b[i] {
				return false
			}
		}
		return true
	}

	StrsEquals := func(a, b []string) bool {
		if len(a) != len(b) {
			return false
		}
		for i, v := range a {
			if v != b[i] {
				return false
			}
		}
		return true
	}
	var expectedIntSlice = []int{22, 80}
	var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"}

	if !IntsEquals(parsedIntSlice, expectedIntSlice) {
		t.Errorf("%v does not match %v", parsedIntSlice, expectedIntSlice)
	}

	if !StrsEquals(parsedStringSlice, expectedStringSlice) {
		t.Errorf("%v does not match %v", parsedStringSlice, expectedStringSlice)
	}
}

func TestApp_ParseSliceFlagsWithMissingValue(t *testing.T) {
	var parsedIntSlice []int
	var parsedStringSlice []string

	app := &App{
		Commands: []*Command{
			{
				Name: "cmd",
				Flags: []Flag{
					&IntSliceFlag{Name: "a", Usage: "set numbers"},
					&StringSliceFlag{Name: "str", Usage: "set strings"},
				},
				Action: func(c *Context) error {
					parsedIntSlice = c.IntSlice("a")
					parsedStringSlice = c.StringSlice("str")
					return nil
				},
			},
		},
	}

	_ = app.Run([]string{"", "cmd", "-a", "2", "-str", "A"})

	var expectedIntSlice = []int{2}
	var expectedStringSlice = []string{"A"}

	if parsedIntSlice[0] != expectedIntSlice[0] {
		t.Errorf("%v does not match %v", parsedIntSlice[0], expectedIntSlice[0])
	}

	if parsedStringSlice[0] != expectedStringSlice[0] {
		t.Errorf("%v does not match %v", parsedIntSlice[0], expectedIntSlice[0])
	}
}

func TestApp_DefaultStdin(t *testing.T) {
	app := &App{}
	app.Setup()

	if app.Reader != os.Stdin {
		t.Error("Default input reader not set.")
	}
}

func TestApp_DefaultStdout(t *testing.T) {
	app := &App{}
	app.Setup()

	if app.Writer != os.Stdout {
		t.Error("Default output writer not set.")
	}
}

func TestApp_SetStdin(t *testing.T) {
	buf := make([]byte, 12)

	app := &App{
		Name:   "test",
		Reader: strings.NewReader("Hello World!"),
		Action: func(c *Context) error {
			_, err := c.App.Reader.Read(buf)
			return err
		},
	}

	err := app.Run([]string{"help"})

	if err != nil {
		t.Fatalf("Run error: %s", err)
	}

	if string(buf) != "Hello World!" {
		t.Error("App did not read input from desired reader.")
	}
}

func TestApp_SetStdin_Subcommand(t *testing.T) {
	buf := make([]byte, 12)

	app := &App{
		Name:   "test",
		Reader: strings.NewReader("Hello World!"),
		Commands: []*Command{
			{
				Name: "command",
				Subcommands: []*Command{
					{
						Name: "subcommand",
						Action: func(c *Context) error {
							_, err := c.App.Reader.Read(buf)
							return err
						},
					},
				},
			},
		},
	}

	err := app.Run([]string{"test", "command", "subcommand"})

	if err != nil {
		t.Fatalf("Run error: %s", err)
	}

	if string(buf) != "Hello World!" {
		t.Error("App did not read input from desired reader.")
	}
}

func TestApp_SetStdout(t *testing.T) {
	var w bytes.Buffer

	app := &App{
		Name:   "test",
		Writer: &w,
	}

	err := app.Run([]string{"help"})

	if err != nil {
		t.Fatalf("Run error: %s", err)
	}

	if w.Len() == 0 {
		t.Error("App did not write output to desired writer.")
	}
}

func TestApp_BeforeFunc(t *testing.T) {
	counts := &opCounts{}
	beforeError := fmt.Errorf("fail")
	var err error

	app := &App{
		Before: func(c *Context) error {
			counts.Total++
			counts.Before = counts.Total
			s := c.String("opt")
			if s == "fail" {
				return beforeError
			}

			return nil
		},
		Commands: []*Command{
			{
				Name: "sub",
				Action: func(c *Context) error {
					counts.Total++
					counts.SubCommand = counts.Total
					return nil
				},
			},
		},
		Flags: []Flag{
			&StringFlag{Name: "opt"},
		},
		Writer: ioutil.Discard,
	}

	// run with the Before() func succeeding
	err = app.Run([]string{"command", "--opt", "succeed", "sub"})

	if err != nil {
		t.Fatalf("Run error: %s", err)
	}

	if counts.Before != 1 {
		t.Errorf("Before() not executed when expected")
	}

	if counts.SubCommand != 2 {
		t.Errorf("Subcommand not executed when expected")
	}

	// reset
	counts = &opCounts{}

	// run with the Before() func failing
	err = app.Run([]string{"command", "--opt", "fail", "sub"})

	// should be the same error produced by the Before func
	if err != beforeError {
		t.Errorf("Run error expected, but not received")
	}

	if counts.Before != 1 {
		t.Errorf("Before() not executed when expected")
	}

	if counts.SubCommand != 0 {
		t.Errorf("Subcommand executed when NOT expected")
	}

	// reset
	counts = &opCounts{}

	afterError := errors.New("fail again")
	app.After = func(_ *Context) error {
		return afterError
	}

	// run with the Before() func failing, wrapped by After()
	err = app.Run([]string{"command", "--opt", "fail", "sub"})

	// should be the same error produced by the Before func
	if _, ok := err.(MultiError); !ok {
		t.Errorf("MultiError expected, but not received")
	}

	if counts.Before != 1 {
		t.Errorf("Before() not executed when expected")
	}

	if counts.SubCommand != 0 {
		t.Errorf("Subcommand executed when NOT expected")
	}
}

func TestApp_BeforeAfterFuncShellCompletion(t *testing.T) {
	counts := &opCounts{}
	var err error

	app := &App{
		EnableBashCompletion: true,
		Before: func(c *Context) error {
			counts.Total++
			counts.Before = counts.Total
			return nil
		},
		After: func(c *Context) error {
			counts.Total++
			counts.After = counts.Total
			return nil
		},
		Commands: []*Command{
			{
				Name: "sub",
				Action: func(c *Context) error {
					counts.Total++
					counts.SubCommand = counts.Total
					return nil
				},
			},
		},
		Flags: []Flag{
			&StringFlag{Name: "opt"},
		},
		Writer: ioutil.Discard,
	}

	// run with the Before() func succeeding
	err = app.Run([]string{"command", "--opt", "succeed", "sub", "--generate-bash-completion"})

	if err != nil {
		t.Fatalf("Run error: %s", err)
	}

	if counts.Before != 0 {
		t.Errorf("Before() executed when not expected")
	}

	if counts.After != 0 {
		t.Errorf("After() executed when not expected")
	}

	if counts.SubCommand != 0 {
		t.Errorf("Subcommand executed more than expected")
	}
}

func TestApp_AfterFunc(t *testing.T) {
	counts := &opCounts{}
	afterError := fmt.Errorf("fail")
	var err error

	app := &App{
		After: func(c *Context) error {
			counts.Total++
			counts.After = counts.Total
			s := c.String("opt")
			if s == "fail" {
				return afterError
			}

			return nil
		},
		Commands: []*Command{
			{
				Name: "sub",
				Action: func(c *Context) error {
					counts.Total++
					counts.SubCommand = counts.Total
					return nil
				},
			},
		},
		Flags: []Flag{
			&StringFlag{Name: "opt"},
		},
	}

	// run with the After() func succeeding
	err = app.Run([]string{"command", "--opt", "succeed", "sub"})

	if err != nil {
		t.Fatalf("Run error: %s", err)
	}

	if counts.After != 2 {
		t.Errorf("After() not executed when expected")
	}

	if counts.SubCommand != 1 {
		t.Errorf("Subcommand not executed when expected")
	}

	// reset
	counts = &opCounts{}

	// run with the Before() func failing
	err = app.Run([]string{"command", "--opt", "fail", "sub"})

	// should be the same error produced by the Before func
	if err != afterError {
		t.Errorf("Run error expected, but not received")
	}

	if counts.After != 2 {
		t.Errorf("After() not executed when expected")
	}

	if counts.SubCommand != 1 {
		t.Errorf("Subcommand not executed when expected")
	}

	/*
		reset
	*/
	counts = &opCounts{}

	// run with none args
	err = app.Run([]string{"command"})

	// should be the same error produced by the Before func
	if err != nil {
		t.Fatalf("Run error: %s", err)
	}

	if counts.After != 1 {
		t.Errorf("After() not executed when expected")
	}

	if counts.SubCommand != 0 {
		t.Errorf("Subcommand not executed when expected")
	}
}

func TestAppNoHelpFlag(t *testing.T) {
	oldFlag := HelpFlag
	defer func() {
		HelpFlag = oldFlag
	}()

	HelpFlag = nil

	app := &App{Writer: ioutil.Discard}
	err := app.Run([]string{"test", "-h"})

	if err != flag.ErrHelp {
		t.Errorf("expected error about missing help flag, but got: %s (%T)", err, err)
	}
}

func TestRequiredFlagAppRunBehavior(t *testing.T) {
	tdata := []struct {
		testCase        string
		appFlags        []Flag
		appRunInput     []string
		appCommands     []*Command
		expectedAnError bool
	}{
		// assertion: empty input, when a required flag is present, errors
		{
			testCase:        "error_case_empty_input_with_required_flag_on_app",
			appRunInput:     []string{"myCLI"},
			appFlags:        []Flag{&StringFlag{Name: "requiredFlag", Required: true}},
			expectedAnError: true,
		},
		{
			testCase:    "error_case_empty_input_with_required_flag_on_command",
			appRunInput: []string{"myCLI", "myCommand"},
			appCommands: []*Command{{
				Name:  "myCommand",
				Flags: []Flag{&StringFlag{Name: "requiredFlag", Required: true}},
			}},
			expectedAnError: true,
		},
		{
			testCase:    "error_case_empty_input_with_required_flag_on_subcommand",
			appRunInput: []string{"myCLI", "myCommand", "mySubCommand"},
			appCommands: []*Command{{
				Name: "myCommand",
				Subcommands: []*Command{{
					Name:  "mySubCommand",
					Flags: []Flag{&StringFlag{Name: "requiredFlag", Required: true}},
				}},
			}},
			expectedAnError: true,
		},
		// assertion: inputting --help, when a required flag is present, does not error
		{
			testCase:    "valid_case_help_input_with_required_flag_on_app",
			appRunInput: []string{"myCLI", "--help"},
			appFlags:    []Flag{&StringFlag{Name: "requiredFlag", Required: true}},
		},
		{
			testCase:    "valid_case_help_input_with_required_flag_on_command",
			appRunInput: []string{"myCLI", "myCommand", "--help"},
			appCommands: []*Command{{
				Name:  "myCommand",
				Flags: []Flag{&StringFlag{Name: "requiredFlag", Required: true}},
			}},
		},
		{
			testCase:    "valid_case_help_input_with_required_flag_on_subcommand",
			appRunInput: []string{"myCLI", "myCommand", "mySubCommand", "--help"},
			appCommands: []*Command{{
				Name: "myCommand",
				Subcommands: []*Command{{
					Name:  "mySubCommand",
					Flags: []Flag{&StringFlag{Name: "requiredFlag", Required: true}},
				}},
			}},
		},
		// assertion: giving optional input, when a required flag is present, errors
		{
			testCase:        "error_case_optional_input_with_required_flag_on_app",
			appRunInput:     []string{"myCLI", "--optional", "cats"},
			appFlags:        []Flag{&StringFlag{Name: "requiredFlag", Required: true}, &StringFlag{Name: "optional"}},
			expectedAnError: true,
		},
		{
			testCase:    "error_case_optional_input_with_required_flag_on_command",
			appRunInput: []string{"myCLI", "myCommand", "--optional", "cats"},
			appCommands: []*Command{{
				Name:  "myCommand",
				Flags: []Flag{&StringFlag{Name: "requiredFlag", Required: true}, &StringFlag{Name: "optional"}},
			}},
			expectedAnError: true,
		},
		{
			testCase:    "error_case_optional_input_with_required_flag_on_subcommand",
			appRunInput: []string{"myCLI", "myCommand", "mySubCommand", "--optional", "cats"},
			appCommands: []*Command{{
				Name: "myCommand",
				Subcommands: []*Command{{
					Name:  "mySubCommand",
					Flags: []Flag{&StringFlag{Name: "requiredFlag", Required: true}, &StringFlag{Name: "optional"}},
				}},
			}},
			expectedAnError: true,
		},
		// assertion: when a required flag is present, inputting that required flag does not error
		{
			testCase:    "valid_case_required_flag_input_on_app",
			appRunInput: []string{"myCLI", "--requiredFlag", "cats"},
			appFlags:    []Flag{&StringFlag{Name: "requiredFlag", Required: true}},
		},
		{
			testCase:    "valid_case_required_flag_input_on_command",
			appRunInput: []string{"myCLI", "myCommand", "--requiredFlag", "cats"},
			appCommands: []*Command{{
				Name:  "myCommand",
				Flags: []Flag{&StringFlag{Name: "requiredFlag", Required: true}},
			}},
		},
		{
			testCase:    "valid_case_required_flag_input_on_subcommand",
			appRunInput: []string{"myCLI", "myCommand", "mySubCommand", "--requiredFlag", "cats"},
			appCommands: []*Command{{
				Name: "myCommand",
				Subcommands: []*Command{{
					Name:  "mySubCommand",
					Flags: []Flag{&StringFlag{Name: "requiredFlag", Required: true}},
					Action: func(c *Context) error {
						return nil
					},
				}},
			}},
		},
	}
	for _, test := range tdata {
		t.Run(test.testCase, func(t *testing.T) {
			// setup
			app := newTestApp()
			app.Flags = test.appFlags
			app.Commands = test.appCommands

			// logic under test
			err := app.Run(test.appRunInput)

			// assertions
			if test.expectedAnError && err == nil {
				t.Errorf("expected an error, but there was none")
			}
			if _, ok := err.(requiredFlagsErr); test.expectedAnError && !ok {
				t.Errorf("expected a requiredFlagsErr, but got: %s", err)
			}
			if !test.expectedAnError && err != nil {
				t.Errorf("did not expected an error, but there was one: %s", err)
			}
		})
	}
}

func TestAppHelpPrinter(t *testing.T) {
	oldPrinter := HelpPrinter
	defer func() {
		HelpPrinter = oldPrinter
	}()

	var wasCalled = false
	HelpPrinter = func(w io.Writer, template string, data interface{}) {
		wasCalled = true
	}

	app := &App{}
	_ = app.Run([]string{"-h"})

	if wasCalled == false {
		t.Errorf("Help printer expected to be called, but was not")
	}
}

func TestApp_VersionPrinter(t *testing.T) {
	oldPrinter := VersionPrinter
	defer func() {
		VersionPrinter = oldPrinter
	}()

	var wasCalled = false
	VersionPrinter = func(c *Context) {
		wasCalled = true
	}

	app := &App{}
	ctx := NewContext(app, nil, nil)
	ShowVersion(ctx)

	if wasCalled == false {
		t.Errorf("Version printer expected to be called, but was not")
	}
}

func TestApp_CommandNotFound(t *testing.T) {
	counts := &opCounts{}
	app := &App{
		CommandNotFound: func(c *Context, command string) {
			counts.Total++
			counts.CommandNotFound = counts.Total
		},
		Commands: []*Command{
			{
				Name: "bar",
				Action: func(c *Context) error {
					counts.Total++
					counts.SubCommand = counts.Total
					return nil
				},
			},
		},
	}

	_ = app.Run([]string{"command", "foo"})

	expect(t, counts.CommandNotFound, 1)
	expect(t, counts.SubCommand, 0)
	expect(t, counts.Total, 1)
}

func TestApp_OrderOfOperations(t *testing.T) {
	counts := &opCounts{}

	resetCounts := func() { counts = &opCounts{} }

	app := &App{
		EnableBashCompletion: true,
		BashComplete: func(c *Context) {
			counts.Total++
			counts.ShellComplete = counts.Total
		},
		OnUsageError: func(c *Context, err error, isSubcommand bool) error {
			counts.Total++
			counts.OnUsageError = counts.Total
			return errors.New("hay OnUsageError")
		},
		Writer: ioutil.Discard,
	}

	beforeNoError := func(c *Context) error {
		counts.Total++
		counts.Before = counts.Total
		return nil
	}

	beforeError := func(c *Context) error {
		counts.Total++
		counts.Before = counts.Total
		return errors.New("hay Before")
	}

	app.Before = beforeNoError
	app.CommandNotFound = func(c *Context, command string) {
		counts.Total++
		counts.CommandNotFound = counts.Total
	}

	afterNoError := func(c *Context) error {
		counts.Total++
		counts.After = counts.Total
		return nil
	}

	afterError := func(c *Context) error {
		counts.Total++
		counts.After = counts.Total
		return errors.New("hay After")
	}

	app.After = afterNoError
	app.Commands = []*Command{
		{
			Name: "bar",
			Action: func(c *Context) error {
				counts.Total++
				counts.SubCommand = counts.Total
				return nil
			},
		},
	}

	app.Action = func(c *Context) error {
		counts.Total++
		counts.Action = counts.Total
		return nil
	}

	_ = app.Run([]string{"command", "--nope"})
	expect(t, counts.OnUsageError, 1)
	expect(t, counts.Total, 1)

	resetCounts()

	_ = app.Run([]string{"command", fmt.Sprintf("--%s", "generate-bash-completion")})
	expect(t, counts.ShellComplete, 1)
	expect(t, counts.Total, 1)

	resetCounts()

	oldOnUsageError := app.OnUsageError
	app.OnUsageError = nil
	_ = app.Run([]string{"command", "--nope"})
	expect(t, counts.Total, 0)
	app.OnUsageError = oldOnUsageError

	resetCounts()

	_ = app.Run([]string{"command", "foo"})
	expect(t, counts.OnUsageError, 0)
	expect(t, counts.Before, 1)
	expect(t, counts.CommandNotFound, 0)
	expect(t, counts.Action, 2)
	expect(t, counts.After, 3)
	expect(t, counts.Total, 3)

	resetCounts()

	app.Before = beforeError
	_ = app.Run([]string{"command", "bar"})
	expect(t, counts.OnUsageError, 0)
	expect(t, counts.Before, 1)
	expect(t, counts.After, 2)
	expect(t, counts.Total, 2)
	app.Before = beforeNoError

	resetCounts()

	app.After = nil
	_ = app.Run([]string{"command", "bar"})
	expect(t, counts.OnUsageError, 0)
	expect(t, counts.Before, 1)
	expect(t, counts.SubCommand, 2)
	expect(t, counts.Total, 2)
	app.After = afterNoError

	resetCounts()

	app.After = afterError
	err := app.Run([]string{"command", "bar"})
	if err == nil {
		t.Fatalf("expected a non-nil error")
	}
	expect(t, counts.OnUsageError, 0)
	expect(t, counts.Before, 1)
	expect(t, counts.SubCommand, 2)
	expect(t, counts.After, 3)
	expect(t, counts.Total, 3)
	app.After = afterNoError

	resetCounts()

	oldCommands := app.Commands
	app.Commands = nil
	_ = app.Run([]string{"command"})
	expect(t, counts.OnUsageError, 0)
	expect(t, counts.Before, 1)
	expect(t, counts.Action, 2)
	expect(t, counts.After, 3)
	expect(t, counts.Total, 3)
	app.Commands = oldCommands
}

func TestApp_Run_CommandWithSubcommandHasHelpTopic(t *testing.T) {
	var subcommandHelpTopics = [][]string{
		{"command", "foo", "--help"},
		{"command", "foo", "-h"},
		{"command", "foo", "help"},
	}

	for _, flagSet := range subcommandHelpTopics {
		t.Run(fmt.Sprintf("checking with flags %v", flagSet), func(t *testing.T) {

			app := &App{}
			buf := new(bytes.Buffer)
			app.Writer = buf

			subCmdBar := &Command{
				Name:  "bar",
				Usage: "does bar things",
			}
			subCmdBaz := &Command{
				Name:  "baz",
				Usage: "does baz things",
			}
			cmd := &Command{
				Name:        "foo",
				Description: "descriptive wall of text about how it does foo things",
				Subcommands: []*Command{subCmdBar, subCmdBaz},
				Action:      func(c *Context) error { return nil },
			}

			app.Commands = []*Command{cmd}
			err := app.Run(flagSet)

			if err != nil {
				t.Error(err)
			}

			output := buf.String()

			if strings.Contains(output, "No help topic for") {
				t.Errorf("expect a help topic, got none: \n%q", output)
			}

			for _, shouldContain := range []string{
				cmd.Name, cmd.Description,
				subCmdBar.Name, subCmdBar.Usage,
				subCmdBaz.Name, subCmdBaz.Usage,
			} {
				if !strings.Contains(output, shouldContain) {
					t.Errorf("want help to contain %q, did not: \n%q", shouldContain, output)
				}
			}
		})
	}
}

func TestApp_Run_SubcommandFullPath(t *testing.T) {
	app := &App{}
	buf := new(bytes.Buffer)
	app.Writer = buf
	app.Name = "command"
	subCmd := &Command{
		Name:  "bar",
		Usage: "does bar things",
	}
	cmd := &Command{
		Name:        "foo",
		Description: "foo commands",
		Subcommands: []*Command{subCmd},
	}
	app.Commands = []*Command{cmd}

	err := app.Run([]string{"command", "foo", "bar", "--help"})
	if err != nil {
		t.Error(err)
	}

	output := buf.String()
	expected := "command foo bar - does bar things"
	if !strings.Contains(output, expected) {
		t.Errorf("expected %q in output: %s", expected, output)
	}

	expected = "command foo bar [command options] [arguments...]"
	if !strings.Contains(output, expected) {
		t.Errorf("expected %q in output: %s", expected, output)
	}
}

func TestApp_Run_SubcommandHelpName(t *testing.T) {
	app := &App{}
	buf := new(bytes.Buffer)
	app.Writer = buf
	app.Name = "command"
	subCmd := &Command{
		Name:     "bar",
		HelpName: "custom",
		Usage:    "does bar things",
	}
	cmd := &Command{
		Name:        "foo",
		Description: "foo commands",
		Subcommands: []*Command{subCmd},
	}
	app.Commands = []*Command{cmd}

	err := app.Run([]string{"command", "foo", "bar", "--help"})
	if err != nil {
		t.Error(err)
	}

	output := buf.String()

	expected := "custom - does bar things"
	if !strings.Contains(output, expected) {
		t.Errorf("expected %q in output: %s", expected, output)
	}

	expected = "custom [command options] [arguments...]"
	if !strings.Contains(output, expected) {
		t.Errorf("expected %q in output: %s", expected, output)
	}
}

func TestApp_Run_CommandHelpName(t *testing.T) {
	app := &App{}
	buf := new(bytes.Buffer)
	app.Writer = buf
	app.Name = "command"
	subCmd := &Command{
		Name:  "bar",
		Usage: "does bar things",
	}
	cmd := &Command{
		Name:        "foo",
		HelpName:    "custom",
		Description: "foo commands",
		Subcommands: []*Command{subCmd},
	}
	app.Commands = []*Command{cmd}

	err := app.Run([]string{"command", "foo", "bar", "--help"})
	if err != nil {
		t.Error(err)
	}

	output := buf.String()

	expected := "command custom bar - does bar things"
	if !strings.Contains(output, expected) {
		t.Errorf("expected %q in output: %s", expected, output)
	}

	expected = "command custom bar [command options] [arguments...]"
	if !strings.Contains(output, expected) {
		t.Errorf("expected %q in output: %s", expected, output)
	}
}

func TestApp_Run_CommandSubcommandHelpName(t *testing.T) {
	app := &App{}
	buf := new(bytes.Buffer)
	app.Writer = buf
	app.Name = "base"
	subCmd := &Command{
		Name:     "bar",
		HelpName: "custom",
		Usage:    "does bar things",
	}
	cmd := &Command{
		Name:        "foo",
		Usage:       "foo commands",
		Description: "This is a description",
		Subcommands: []*Command{subCmd},
	}
	app.Commands = []*Command{cmd}

	err := app.Run([]string{"command", "foo", "--help"})
	if err != nil {
		t.Error(err)
	}

	output := buf.String()

	expected := "base foo - foo commands"
	if !strings.Contains(output, expected) {
		t.Errorf("expected %q in output: %q", expected, output)
	}

	expected = "DESCRIPTION:\n   This is a description\n"
	if !strings.Contains(output, expected) {
		t.Errorf("expected %q in output: %q", expected, output)
	}

	expected = "base foo command [command options] [arguments...]"
	if !strings.Contains(output, expected) {
		t.Errorf("expected %q in output: %q", expected, output)
	}
}

func TestApp_Run_Help(t *testing.T) {
	var tests = []struct {
		helpArguments []string
		hideHelp      bool
		wantContains  string
		wantErr       error
	}{
		{
			helpArguments: []string{"boom", "--help"},
			hideHelp:      false,
			wantContains:  "boom - make an explosive entrance",
		},
		{
			helpArguments: []string{"boom", "-h"},
			hideHelp:      false,
			wantContains:  "boom - make an explosive entrance",
		},
		{
			helpArguments: []string{"boom", "help"},
			hideHelp:      false,
			wantContains:  "boom - make an explosive entrance",
		},
		{
			helpArguments: []string{"boom", "--help"},
			hideHelp:      true,
			wantErr:       fmt.Errorf("flag: help requested"),
		},
		{
			helpArguments: []string{"boom", "-h"},
			hideHelp:      true,
			wantErr:       fmt.Errorf("flag: help requested"),
		},
		{
			helpArguments: []string{"boom", "help"},
			hideHelp:      true,
			wantContains:  "boom I say!",
		},
	}

	for _, tt := range tests {
		t.Run(fmt.Sprintf("checking with arguments %v", tt.helpArguments), func(t *testing.T) {
			buf := new(bytes.Buffer)

			app := &App{
				Name:     "boom",
				Usage:    "make an explosive entrance",
				Writer:   buf,
				HideHelp: tt.hideHelp,
				Action: func(c *Context) error {
					buf.WriteString("boom I say!")
					return nil
				},
			}

			err := app.Run(tt.helpArguments)
			if err != nil && tt.wantErr != nil && err.Error() != tt.wantErr.Error() {
				t.Errorf("want err: %s, did note %s\n", tt.wantErr, err)
			}

			output := buf.String()

			if !strings.Contains(output, tt.wantContains) {
				t.Errorf("want help to contain %q, did not: \n%q", "boom - make an explosive entrance", output)
			}
		})
	}
}

func TestApp_Run_Version(t *testing.T) {
	var versionArguments = [][]string{{"boom", "--version"}, {"boom", "-v"}}

	for _, args := range versionArguments {
		t.Run(fmt.Sprintf("checking with arguments %v", args), func(t *testing.T) {

			buf := new(bytes.Buffer)

			app := &App{
				Name:    "boom",
				Usage:   "make an explosive entrance",
				Version: "0.1.0",
				Writer:  buf,
				Action: func(c *Context) error {
					buf.WriteString("boom I say!")
					return nil
				},
			}

			err := app.Run(args)
			if err != nil {
				t.Error(err)
			}

			output := buf.String()

			if !strings.Contains(output, "0.1.0") {
				t.Errorf("want version to contain %q, did not: \n%q", "0.1.0", output)
			}
		})
	}
}

func TestApp_Run_Categories(t *testing.T) {
	buf := new(bytes.Buffer)

	app := &App{
		Name:     "categories",
		HideHelp: true,
		Commands: []*Command{
			{
				Name:     "command1",
				Category: "1",
			},
			{
				Name:     "command2",
				Category: "1",
			},
			{
				Name:     "command3",
				Category: "2",
			},
		},
		Writer: buf,
	}

	_ = app.Run([]string{"categories"})

	expect := commandCategories([]*commandCategory{
		{
			name: "1",
			commands: []*Command{
				app.Commands[0],
				app.Commands[1],
			},
		},
		{
			name: "2",
			commands: []*Command{
				app.Commands[2],
			},
		},
	})

	if !reflect.DeepEqual(app.categories, &expect) {
		t.Fatalf("expected categories %#v, to equal %#v", app.categories, &expect)
	}

	output := buf.String()

	if !strings.Contains(output, "1:\n     command1") {
		t.Errorf("want buffer to include category %q, did not: \n%q", "1:\n     command1", output)
	}
}

func TestApp_VisibleCategories(t *testing.T) {
	app := &App{
		Name:     "visible-categories",
		HideHelp: true,
		Commands: []*Command{
			{
				Name:     "command1",
				Category: "1",
				HelpName: "foo command1",
				Hidden:   true,
			},
			{
				Name:     "command2",
				Category: "2",
				HelpName: "foo command2",
			},
			{
				Name:     "command3",
				Category: "3",
				HelpName: "foo command3",
			},
		},
	}

	expected := []CommandCategory{
		&commandCategory{
			name: "2",
			commands: []*Command{
				app.Commands[1],
			},
		},
		&commandCategory{
			name: "3",
			commands: []*Command{
				app.Commands[2],
			},
		},
	}

	app.Setup()
	expect(t, expected, app.VisibleCategories())

	app = &App{
		Name:     "visible-categories",
		HideHelp: true,
		Commands: []*Command{
			{
				Name:     "command1",
				Category: "1",
				HelpName: "foo command1",
				Hidden:   true,
			},
			{
				Name:     "command2",
				Category: "2",
				HelpName: "foo command2",
				Hidden:   true,
			},
			{
				Name:     "command3",
				Category: "3",
				HelpName: "foo command3",
			},
		},
	}

	expected = []CommandCategory{
		&commandCategory{
			name: "3",
			commands: []*Command{
				app.Commands[2],
			},
		},
	}

	app.Setup()
	expect(t, expected, app.VisibleCategories())

	app = &App{
		Name:     "visible-categories",
		HideHelp: true,
		Commands: []*Command{
			{
				Name:     "command1",
				Category: "1",
				HelpName: "foo command1",
				Hidden:   true,
			},
			{
				Name:     "command2",
				Category: "2",
				HelpName: "foo command2",
				Hidden:   true,
			},
			{
				Name:     "command3",
				Category: "3",
				HelpName: "foo command3",
				Hidden:   true,
			},
		},
	}

	app.Setup()
	expect(t, []CommandCategory{}, app.VisibleCategories())
}

func TestApp_VisibleFlagCategories(t *testing.T) {
	app := &App{
		Flags: []Flag{
			&StringFlag{
				Name: "strd", // no category set
			},
			&Int64Flag{
				Name:     "intd",
				Aliases:  []string{"altd1", "altd2"},
				Category: "cat1",
			},
		},
	}
	app.Setup()
	vfc := app.VisibleFlagCategories()
	if len(vfc) != 1 {
		t.Fatalf("unexpected visible flag categories %+v", vfc)
	}
	if vfc[0].Name() != "cat1" {
		t.Errorf("expected category name cat1 got %s", vfc[0].Name())
	}
	if len(vfc[0].Flags()) != 1 {
		t.Fatalf("expected flag category to have just one flag got %+v", vfc[0].Flags())
	}

	fl := vfc[0].Flags()[0]
	if !reflect.DeepEqual(fl.Names(), []string{"intd", "altd1", "altd2"}) {
		t.Errorf("unexpected flag %+v", fl.Names())
	}
}

func TestApp_Run_DoesNotOverwriteErrorFromBefore(t *testing.T) {
	app := &App{
		Action: func(c *Context) error { return nil },
		Before: func(c *Context) error { return fmt.Errorf("before error") },
		After:  func(c *Context) error { return fmt.Errorf("after error") },
		Writer: ioutil.Discard,
	}

	err := app.Run([]string{"foo"})
	if err == nil {
		t.Fatalf("expected to receive error from Run, got none")
	}

	if !strings.Contains(err.Error(), "before error") {
		t.Errorf("expected text of error from Before method, but got none in \"%v\"", err)
	}
	if !strings.Contains(err.Error(), "after error") {
		t.Errorf("expected text of error from After method, but got none in \"%v\"", err)
	}
}

func TestApp_Run_SubcommandDoesNotOverwriteErrorFromBefore(t *testing.T) {
	app := &App{
		Commands: []*Command{
			{
				Subcommands: []*Command{
					{
						Name: "sub",
					},
				},
				Name:   "bar",
				Before: func(c *Context) error { return fmt.Errorf("before error") },
				After:  func(c *Context) error { return fmt.Errorf("after error") },
			},
		},
	}

	err := app.Run([]string{"foo", "bar"})
	if err == nil {
		t.Fatalf("expected to receive error from Run, got none")
	}

	if !strings.Contains(err.Error(), "before error") {
		t.Errorf("expected text of error from Before method, but got none in \"%v\"", err)
	}
	if !strings.Contains(err.Error(), "after error") {
		t.Errorf("expected text of error from After method, but got none in \"%v\"", err)
	}
}

func TestApp_OnUsageError_WithWrongFlagValue(t *testing.T) {
	app := &App{
		Flags: []Flag{
			&IntFlag{Name: "flag"},
		},
		OnUsageError: func(c *Context, err error, isSubcommand bool) error {
			if isSubcommand {
				t.Errorf("Expect no subcommand")
			}
			if !strings.HasPrefix(err.Error(), "invalid value \"wrong\"") {
				t.Errorf("Expect an invalid value error, but got \"%v\"", err)
			}
			return errors.New("intercepted: " + err.Error())
		},
		Commands: []*Command{
			{
				Name: "bar",
			},
		},
	}

	err := app.Run([]string{"foo", "--flag=wrong"})
	if err == nil {
		t.Fatalf("expected to receive error from Run, got none")
	}

	if !strings.HasPrefix(err.Error(), "intercepted: invalid value") {
		t.Errorf("Expect an intercepted error, but got \"%v\"", err)
	}
}

func TestApp_OnUsageError_WithWrongFlagValue_ForSubcommand(t *testing.T) {
	app := &App{
		Flags: []Flag{
			&IntFlag{Name: "flag"},
		},
		OnUsageError: func(c *Context, err error, isSubcommand bool) error {
			if isSubcommand {
				t.Errorf("Expect subcommand")
			}
			if !strings.HasPrefix(err.Error(), "invalid value \"wrong\"") {
				t.Errorf("Expect an invalid value error, but got \"%v\"", err)
			}
			return errors.New("intercepted: " + err.Error())
		},
		Commands: []*Command{
			{
				Name: "bar",
			},
		},
	}

	err := app.Run([]string{"foo", "--flag=wrong", "bar"})
	if err == nil {
		t.Fatalf("expected to receive error from Run, got none")
	}

	if !strings.HasPrefix(err.Error(), "intercepted: invalid value") {
		t.Errorf("Expect an intercepted error, but got \"%v\"", err)
	}
}

// A custom flag that conforms to the relevant interfaces, but has none of the
// fields that the other flag types do.
type customBoolFlag struct {
	Nombre string
}

// Don't use the normal FlagStringer
func (c *customBoolFlag) String() string {
	return "***" + c.Nombre + "***"
}

func (c *customBoolFlag) Names() []string {
	return []string{c.Nombre}
}

func (c *customBoolFlag) TakesValue() bool {
	return false
}

func (c *customBoolFlag) GetValue() string {
	return "value"
}

func (c *customBoolFlag) GetUsage() string {
	return "usage"
}

func (c *customBoolFlag) Apply(set *flag.FlagSet) error {
	set.String(c.Nombre, c.Nombre, "")
	return nil
}

func (c *customBoolFlag) RunAction(*Context) error {
	return nil
}

func (c *customBoolFlag) IsSet() bool {
	return false
}

func (c *customBoolFlag) IsRequired() bool {
	return false
}

func (c *customBoolFlag) IsVisible() bool {
	return false
}

func (c *customBoolFlag) GetCategory() string {
	return ""
}

func (c *customBoolFlag) GetEnvVars() []string {
	return nil
}

func (c *customBoolFlag) GetDefaultText() string {
	return ""
}

func TestCustomFlagsUnused(t *testing.T) {
	app := &App{
		Flags:  []Flag{&customBoolFlag{"custom"}},
		Writer: ioutil.Discard,
	}

	err := app.Run([]string{"foo"})
	if err != nil {
		t.Errorf("Run returned unexpected error: %v", err)
	}
}

func TestCustomFlagsUsed(t *testing.T) {
	app := &App{
		Flags:  []Flag{&customBoolFlag{"custom"}},
		Writer: ioutil.Discard,
	}

	err := app.Run([]string{"foo", "--custom=bar"})
	if err != nil {
		t.Errorf("Run returned unexpected error: %v", err)
	}
}

func TestCustomHelpVersionFlags(t *testing.T) {
	app := &App{
		Writer: ioutil.Discard,
	}

	// Be sure to reset the global flags
	defer func(helpFlag Flag, versionFlag Flag) {
		HelpFlag = helpFlag.(*BoolFlag)
		VersionFlag = versionFlag.(*BoolFlag)
	}(HelpFlag, VersionFlag)

	HelpFlag = &customBoolFlag{"help-custom"}
	VersionFlag = &customBoolFlag{"version-custom"}

	err := app.Run([]string{"foo", "--help-custom=bar"})
	if err != nil {
		t.Errorf("Run returned unexpected error: %v", err)
	}
}

func TestHandleExitCoder_Default(t *testing.T) {
	app := newTestApp()
	fs, err := flagSet(app.Name, app.Flags)
	if err != nil {
		t.Errorf("error creating FlagSet: %s", err)
	}

	ctx := NewContext(app, fs, nil)
	app.handleExitCoder(ctx, NewExitError("Default Behavior Error", 42))

	output := fakeErrWriter.String()
	if !strings.Contains(output, "Default") {
		t.Fatalf("Expected Default Behavior from Error Handler but got: %s", output)
	}
}

func TestHandleExitCoder_Custom(t *testing.T) {
	app := newTestApp()
	fs, err := flagSet(app.Name, app.Flags)
	if err != nil {
		t.Errorf("error creating FlagSet: %s", err)
	}

	app.ExitErrHandler = func(_ *Context, _ error) {
		_, _ = fmt.Fprintln(ErrWriter, "I'm a Custom error handler, I print what I want!")
	}

	ctx := NewContext(app, fs, nil)
	app.handleExitCoder(ctx, NewExitError("Default Behavior Error", 42))

	output := fakeErrWriter.String()
	if !strings.Contains(output, "Custom") {
		t.Fatalf("Expected Custom Behavior from Error Handler but got: %s", output)
	}
}

func TestShellCompletionForIncompleteFlags(t *testing.T) {
	app := &App{
		Flags: []Flag{
			&IntFlag{
				Name: "test-completion",
			},
		},
		EnableBashCompletion: true,
		BashComplete: func(ctx *Context) {
			for _, command := range ctx.App.Commands {
				if command.Hidden {
					continue
				}

				for _, name := range command.Names() {
					_, _ = fmt.Fprintln(ctx.App.Writer, name)
				}
			}

			for _, fl := range ctx.App.Flags {
				for _, name := range fl.Names() {
					if name == BashCompletionFlag.Names()[0] {
						continue
					}

					switch name = strings.TrimSpace(name); len(name) {
					case 0:
					case 1:
						_, _ = fmt.Fprintln(ctx.App.Writer, "-"+name)
					default:
						_, _ = fmt.Fprintln(ctx.App.Writer, "--"+name)
					}
				}
			}
		},
		Action: func(ctx *Context) error {
			return fmt.Errorf("should not get here")
		},
		Writer: ioutil.Discard,
	}
	err := app.Run([]string{"", "--test-completion", "--" + "generate-bash-completion"})
	if err != nil {
		t.Errorf("app should not return an error: %s", err)
	}
}

func TestWhenExitSubCommandWithCodeThenAppQuitUnexpectedly(t *testing.T) {
	testCode := 104

	app := newTestApp()
	app.Commands = []*Command{
		{
			Name: "cmd",
			Subcommands: []*Command{
				{
					Name: "subcmd",
					Action: func(c *Context) error {
						return NewExitError("exit error", testCode)
					},
				},
			},
		},
	}

	// set user function as ExitErrHandler
	var exitCodeFromExitErrHandler int
	app.ExitErrHandler = func(c *Context, err error) {
		if exitErr, ok := err.(ExitCoder); ok {
			exitCodeFromExitErrHandler = exitErr.ExitCode()
		}
	}

	// keep and restore original OsExiter
	origExiter := OsExiter
	defer func() {
		OsExiter = origExiter
	}()

	// set user function as OsExiter
	var exitCodeFromOsExiter int
	OsExiter = func(exitCode int) {
		exitCodeFromOsExiter = exitCode
	}

	_ = app.Run([]string{
		"myapp",
		"cmd",
		"subcmd",
	})

	if exitCodeFromOsExiter != 0 {
		t.Errorf("exitCodeFromExitErrHandler should not change, but its value is %v", exitCodeFromOsExiter)
	}

	if exitCodeFromExitErrHandler != testCode {
		t.Errorf("exitCodeFromOsExiter value should be %v, but its value is %v", testCode, exitCodeFromExitErrHandler)
	}
}

func newTestApp() *App {
	a := NewApp()
	a.Writer = ioutil.Discard
	return a
}

func TestSetupInitializesBothWriters(t *testing.T) {
	a := &App{}

	a.Setup()

	if a.ErrWriter != os.Stderr {
		t.Errorf("expected a.ErrWriter to be os.Stderr")
	}

	if a.Writer != os.Stdout {
		t.Errorf("expected a.Writer to be os.Stdout")
	}
}

func TestSetupInitializesOnlyNilWriters(t *testing.T) {
	wr := &bytes.Buffer{}
	a := &App{
		ErrWriter: wr,
	}

	a.Setup()

	if a.ErrWriter != wr {
		t.Errorf("expected a.ErrWriter to be a *bytes.Buffer instance")
	}

	if a.Writer != os.Stdout {
		t.Errorf("expected a.Writer to be os.Stdout")
	}
}

func TestFlagAction(t *testing.T) {
	stringFlag := &StringFlag{
		Name: "f_string",
		Action: func(c *Context, v string) error {
			if v == "" {
				return fmt.Errorf("empty string")
			}
			c.App.Writer.Write([]byte(v + " "))
			return nil
		},
	}
	app := &App{
		Name: "app",
		Commands: []*Command{
			{
				Name:   "c1",
				Flags:  []Flag{stringFlag},
				Action: func(ctx *Context) error { return nil },
				Subcommands: []*Command{
					{
						Name:   "sub1",
						Action: func(ctx *Context) error { return nil },
						Flags:  []Flag{stringFlag},
					},
				},
			},
		},
		Flags: []Flag{
			stringFlag,
			&StringFlag{
				Name: "f_no_action",
			},
			&StringSliceFlag{
				Name: "f_string_slice",
				Action: func(c *Context, v []string) error {
					if v[0] == "err" {
						return fmt.Errorf("error string slice")
					}
					c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
					return nil
				},
			},
			&BoolFlag{
				Name: "f_bool",
				Action: func(c *Context, v bool) error {
					if !v {
						return fmt.Errorf("value is false")
					}
					c.App.Writer.Write([]byte(fmt.Sprintf("%t ", v)))
					return nil
				},
			},
			&DurationFlag{
				Name: "f_duration",
				Action: func(c *Context, v time.Duration) error {
					if v == 0 {
						return fmt.Errorf("empty duration")
					}
					c.App.Writer.Write([]byte(v.String() + " "))
					return nil
				},
			},
			&Float64Flag{
				Name: "f_float64",
				Action: func(c *Context, v float64) error {
					if v < 0 {
						return fmt.Errorf("negative float64")
					}
					c.App.Writer.Write([]byte(strconv.FormatFloat(v, 'f', -1, 64) + " "))
					return nil
				},
			},
			&Float64SliceFlag{
				Name: "f_float64_slice",
				Action: func(c *Context, v []float64) error {
					if len(v) > 0 && v[0] < 0 {
						return fmt.Errorf("invalid float64 slice")
					}
					c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
					return nil
				},
			},
			&GenericFlag{
				Name:  "f_generic",
				Value: new(stringGeneric),
				Action: func(c *Context, v interface{}) error {
					fmt.Printf("%T %v\n", v, v)
					switch vv := v.(type) {
					case *stringGeneric:
						if vv.value == "" {
							return fmt.Errorf("generic value not set")
						}
					}

					c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
					return nil
				},
			},
			&IntFlag{
				Name: "f_int",
				Action: func(c *Context, v int) error {
					if v < 0 {
						return fmt.Errorf("negative int")
					}
					c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
					return nil
				},
			},
			&IntSliceFlag{
				Name: "f_int_slice",
				Action: func(c *Context, v []int) error {
					if len(v) > 0 && v[0] < 0 {
						return fmt.Errorf("invalid int slice")
					}
					c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
					return nil
				},
			},
			&Int64Flag{
				Name: "f_int64",
				Action: func(c *Context, v int64) error {
					if v < 0 {
						return fmt.Errorf("negative int64")
					}
					c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
					return nil
				},
			},
			&Int64SliceFlag{
				Name: "f_int64_slice",
				Action: func(c *Context, v []int64) error {
					if len(v) > 0 && v[0] < 0 {
						return fmt.Errorf("invalid int64 slice")
					}
					c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
					return nil
				},
			},
			&PathFlag{
				Name: "f_path",
				Action: func(c *Context, v string) error {
					if v == "" {
						return fmt.Errorf("empty path")
					}
					c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
					return nil
				},
			},
			&TimestampFlag{
				Name:   "f_timestamp",
				Layout: "2006-01-02 15:04:05",
				Action: func(c *Context, v *time.Time) error {
					if v.IsZero() {
						return fmt.Errorf("zero timestamp")
					}
					c.App.Writer.Write([]byte(v.Format(time.RFC3339) + " "))
					return nil
				},
			},
			&UintFlag{
				Name: "f_uint",
				Action: func(c *Context, v uint) error {
					if v == 0 {
						return fmt.Errorf("zero uint")
					}
					c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
					return nil
				},
			},
			&Uint64Flag{
				Name: "f_uint64",
				Action: func(c *Context, v uint64) error {
					if v == 0 {
						return fmt.Errorf("zero uint64")
					}
					c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
					return nil
				},
			},
		},
		Action: func(ctx *Context) error { return nil },
	}

	tests := []struct {
		name string
		args []string
		err  error
		exp  string
	}{
		{
			name: "flag_string",
			args: []string{"app", "--f_string=string"},
			exp:  "string ",
		},
		{
			name: "flag_string_error",
			args: []string{"app", "--f_string="},
			err:  fmt.Errorf("empty string"),
		},
		{
			name: "flag_string_slice",
			args: []string{"app", "--f_string_slice=s1,s2,s3"},
			exp:  "[s1 s2 s3] ",
		},
		{
			name: "flag_string_slice_error",
			args: []string{"app", "--f_string_slice=err"},
			err:  fmt.Errorf("error string slice"),
		},
		{
			name: "flag_bool",
			args: []string{"app", "--f_bool"},
			exp:  "true ",
		},
		{
			name: "flag_bool_error",
			args: []string{"app", "--f_bool=false"},
			err:  fmt.Errorf("value is false"),
		},
		{
			name: "flag_duration",
			args: []string{"app", "--f_duration=1h30m20s"},
			exp:  "1h30m20s ",
		},
		{
			name: "flag_duration_error",
			args: []string{"app", "--f_duration=0"},
			err:  fmt.Errorf("empty duration"),
		},
		{
			name: "flag_float64",
			args: []string{"app", "--f_float64=3.14159"},
			exp:  "3.14159 ",
		},
		{
			name: "flag_float64_error",
			args: []string{"app", "--f_float64=-1"},
			err:  fmt.Errorf("negative float64"),
		},
		{
			name: "flag_float64_slice",
			args: []string{"app", "--f_float64_slice=1.1,2.2,3.3"},
			exp:  "[1.1 2.2 3.3] ",
		},
		{
			name: "flag_float64_slice_error",
			args: []string{"app", "--f_float64_slice=-1"},
			err:  fmt.Errorf("invalid float64 slice"),
		},
		{
			name: "flag_generic",
			args: []string{"app", "--f_generic=1"},
			exp:  "1 ",
		},
		{
			name: "flag_generic_error",
			args: []string{"app", "--f_generic="},
			err:  fmt.Errorf("generic value not set"),
		},
		{
			name: "flag_int",
			args: []string{"app", "--f_int=1"},
			exp:  "1 ",
		},
		{
			name: "flag_int_error",
			args: []string{"app", "--f_int=-1"},
			err:  fmt.Errorf("negative int"),
		},
		{
			name: "flag_int_slice",
			args: []string{"app", "--f_int_slice=1,2,3"},
			exp:  "[1 2 3] ",
		},
		{
			name: "flag_int_slice_error",
			args: []string{"app", "--f_int_slice=-1"},
			err:  fmt.Errorf("invalid int slice"),
		},
		{
			name: "flag_int64",
			args: []string{"app", "--f_int64=1"},
			exp:  "1 ",
		},
		{
			name: "flag_int64_error",
			args: []string{"app", "--f_int64=-1"},
			err:  fmt.Errorf("negative int64"),
		},
		{
			name: "flag_int64_slice",
			args: []string{"app", "--f_int64_slice=1,2,3"},
			exp:  "[1 2 3] ",
		},
		{
			name: "flag_int64_slice",
			args: []string{"app", "--f_int64_slice=-1"},
			err:  fmt.Errorf("invalid int64 slice"),
		},
		{
			name: "flag_path",
			args: []string{"app", "--f_path=/root"},
			exp:  "/root ",
		},
		{
			name: "flag_path_error",
			args: []string{"app", "--f_path="},
			err:  fmt.Errorf("empty path"),
		},
		{
			name: "flag_timestamp",
			args: []string{"app", "--f_timestamp", "2022-05-01 02:26:20"},
			exp:  "2022-05-01T02:26:20Z ",
		},
		{
			name: "flag_timestamp_error",
			args: []string{"app", "--f_timestamp", "0001-01-01 00:00:00"},
			err:  fmt.Errorf("zero timestamp"),
		},
		{
			name: "flag_uint",
			args: []string{"app", "--f_uint=1"},
			exp:  "1 ",
		},
		{
			name: "flag_uint_error",
			args: []string{"app", "--f_uint=0"},
			err:  fmt.Errorf("zero uint"),
		},
		{
			name: "flag_uint64",
			args: []string{"app", "--f_uint64=1"},
			exp:  "1 ",
		},
		{
			name: "flag_uint64_error",
			args: []string{"app", "--f_uint64=0"},
			err:  fmt.Errorf("zero uint64"),
		},
		{
			name: "flag_no_action",
			args: []string{"app", "--f_no_action="},
			exp:  "",
		},
		{
			name: "command_flag",
			args: []string{"app", "c1", "--f_string=c1"},
			exp:  "c1 ",
		},
		{
			name: "subCommand_flag",
			args: []string{"app", "c1", "sub1", "--f_string=sub1"},
			exp:  "sub1 ",
		},
		{
			name: "mixture",
			args: []string{"app", "--f_string=app", "--f_uint=1", "--f_int_slice=1,2,3", "--f_duration=1h30m20s", "c1", "--f_string=c1", "sub1", "--f_string=sub1"},
			exp:  "app 1h30m20s [1 2 3] 1 c1 sub1 ",
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			buf := new(bytes.Buffer)
			app.Writer = buf
			err := app.Run(test.args)
			if test.err != nil {
				expect(t, err, test.err)
			} else {
				expect(t, err, nil)
				expect(t, buf.String(), test.exp)
			}
		})
	}
}

redpajama_set_name: RedPajamaGithub


text:
/*jslint sloppy: true, browser: true, devel: true */
/*global enyo, moboreader*/

enyo.singleton({
	name: "ArticleContentHandler",
	published: {
		dbActivities: 0,
		isWebos: true
	},
	activityId: 0,
	storage: {}, //used if not webOS.
	needDL: [],
	checkQueue: [],

	//signals:
	//onArticleOpReturned => success true/false, activityId, content { web, spritz} (optional), id = articleId

	components: [
		{
			kind: "enyo.Signals",
			onArticleDownloaded: "contentDownloaded"
		}
	],

	debugOut: function (msg) {
		//noop or console.error for on device debugging.
		console.log(msg);
		return undefined;
	},

	create: function () {
		this.inherited(arguments);
		this.log("Have PalmSystem: " + (!!window.PalmSystem));
		this.setIsWebos(!!window.PalmSystem);
	},

	storeArticle: function (articleModel, webContent, spritzContent, images) {
		this.activityId += 1;

		this.setDbActivities(this.dbActivities + 1);
		this.privateGenericSend(articleModel, "storeArticleContent", {
			content: {
				web: webContent,
				spritz: spritzContent,
				images: images
			},
			activityId: this.activityId
		});
		return this.activityId;
	},

	privateGenericSend: function (articleModel, method, inParams) {
		var params = inParams || {}, req;

		if (articleModel) {
			if (articleModel.get) {
				params.id = articleModel.get(articleModel.primaryKey);
			} else {
				params.id = articleModel.item_id;
			}
		}

		if (!params.activityId) {
			this.activityId += 1;
			params.activityId = this.activityId;
			this.setDbActivities(this.dbActivities + 1);
		}

		if (this.isWebos) {
			req = new enyo.ServiceRequest({
				service: "palm://info.mobo.moboreader.service",
				method: method
			});
			req.response(this.dbActivityComplete.bind(this, params.activityId, params.id, method, params.onSuccess));
			req.error(this.dbError.bind(this, params.activityId, params.id, method, params.onFailure));

			req.go(params);
		} else {
			if (params.content) {
				this.storage[params.id] = params.content;
			}
			setTimeout(function (activityId) {
				this.dbActivityComplete(activityId, params.id, method, this, {
					success: method === "articleContentExists" ? !!(params.id && this.storage[params.id]) : true,
					id: params.id,
					content: params.id ? this.storage[params.id] : undefined,
					activityId: activityId
				});
			}.bind(this, this.activityId), 100);
		}
		return this.activityId;
	},
	getContent: function (articleModel, params) {
		return this.privateGenericSend(articleModel, "getArticleContent", params);
	},
	articleContentExists: function (articleModel, params) {
		if (undefined === params.requireSpritz) {
			params.requireSpritz = moboreader.Prefs.downloadSpritzOnUpdate;
		}
		return this.privateGenericSend(articleModel, "articleContentExists", params);
	},
	deleteContent: function (articleModel) {
		return this.privateGenericSend(articleModel, "deleteArticleContent");
	},
	wipe: function () {
		return this.privateGenericSend(null, "wipeStorage");
	},

	//============================ checkAndDownload ======
	checkAndDownload: function (articleModel, api) {
		if (!articleModel) {
			this.log("Article undefined: " + JSON.stringify(articleModel));
			return;
		}

		var id = articleModel.get(articleModel.primaryKey), activityId;
		if (!this.checking) {
			this.checking = id;
			activityId = this.articleContentExists(articleModel, {
				onSuccess: function (inEvent) {
					if (!inEvent.success) {
						this.debugOut("Need download: " + id);
						articleModel.set("contentAvailable", false);
						this.needDL.push({model: articleModel, api: api});
					} else {
						this.log("Article ok, don't download.");
						articleModel.set("contentAvailable", true);
					}
					this.checking = false;
					this.sendNext();
					this.downloadNext();
				}.bind(this)
			});
			this.debugOut("Checking: " + id + " witch activity " + activityId);
		} else {
			this.debugOut("Checking LATER: " + id + " currently doing: " + this.checking);
			this.checkQueue.unshift({
				model: articleModel,
				api: api
			});
		}
	},

	downloadMultiple: function (models, api, inEvent) {
		this.debugOut("Got multiple result: " + JSON.stringify(inEvent.idsStatus));
		function getModelById(id) {
			var i;
			for (i = 0; i < models.length; i += 1) {
				if (models[i].get(models[i].primaryKey) === id) {
					return models[i];
				}
			}
		}

		var status = inEvent.idsStatus;
		if (status) {
			Object.keys(status).forEach(function processContentStatus(id) {
				var model = getModelById(id);
				if (!model) {
					this.warn("No model for id " + id);
					return;
				}
				if (status[id].all) {
					model.set("contentAvailable", true);
					this.debugOut(id + " all there, no need to dl.");
				} else {
					model.set("contentAvailable", false);
					this.needDL.push({
						model: model,
						api: api,
						onlyImages: (status[id].web && status[id].spritz) //only need images, call service to handle that.
					});
				}
			}.bind(this));
		}

		this.downloadNext();
	},
	checkAndDownloadMultiple: function (ids, models, api) {
		this.privateGenericSend(null, "articleContentExists", {
			ids: ids,
			requireSpritz: moboreader.Prefs.downloadSpritzOnUpdate,
			onSuccess: this.downloadMultiple.bind(this, models, api),
			onFailure: function () { console.error("Failed to check events for required downloads."); }
		});
	},

	contentDownloaded: function (inSender, inEvent) {
		/*jslint unparam: true */
		this.debugOut("Download finished: " + inEvent.model.get(inEvent.model.primaryKey));
		inEvent.model.set("contentAvailable", !!(inEvent.content && inEvent.content.web && (inEvent.content.spritz || !moboreader.Prefs.downloadSpritzOnUpdate)));
		this.storeArticle(inEvent.model, inEvent.content.web, inEvent.content.spritz, inEvent.content.images);

		if (inEvent.model.get(inEvent.model.primaryKey) === this.downloading) {
			this.downloading = false;
		}

		this.downloadNext();
	},

	downloadNext: function () {
		if (this.downloading) {
			this.debugOut("Already downloading " + this.downloading + ". Waiting downloads: " + this.needDL.length + ".");
			return;
		}
		if (this.timeout) {
			clearTimeout(this.timeout);
			this.timeout = false;
		}

		if (this.needDL.length > 0) {
			var obj = this.needDL.shift();
			if (obj.onlyImages) {
				this.debugOut("Need only images.");
				this.privateGenericSend(obj.model, "downloadImages");
			} else {
				this.debugOut("Need article content.");
				obj.api.getArticleContent(obj.model);
			}
			this.downloading = obj.model.get(obj.model.primaryKey);
			this.debugOut("Download started: " + this.downloading);

			if (this.needDL.length) {
				if (!this.timeout) {
					this.timeout = setTimeout(function () {
						this.debugOut("Download of " + this.downloading + " taking too long. Do next one.");
						this.downloading = false;
						this.timeout = false;
						this.downloadNext();
					}.bind(this), 30000);
				}
			}
		} else {
			this.debugOut("all downloads finished.");
			this.downloading = false;
		}
	},
	//this will mix queue a bit up.. hm..
	sendNext: function (doneId, method) {
		if (doneId === this.checking && method === "articleContentExists") {
			this.debugOut("Check of " + this.checking + " done.");
			this.checking = false;
		}
		if (doneId === this.downloading && method === "downloadImages") {
			this.debugOut("Download of " + this.downloading + " done.");
			this.downloading = false;
		}
		var req = this.checkQueue.shift();
		if (req) {
			this.checkAndDownload(req.model, req.api);
		} else {
			this.downloadNext();
		}
	},
	dbActivityComplete: function (activityId, id, method, callback, inSender, inEvent) {
		/*jslint unparam: true */
		this.debugOut("Incomming response: " + inEvent.success + " for id " + activityId + " and model id " + id);
		this.setDbActivities(this.dbActivities - 1);
		inEvent.activityId = activityId;
		inEvent.id = id;
		inEvent.method = method;
		enyo.Signals.send("onArticleOpReturned", inEvent);
		this.sendNext(id, method);
		if (typeof callback === "function") {
			callback(inEvent);
		}
	},
	dbError: function (activityId, id, method, callback, inSender, inEvent) {
		/*jslint unparam: true */
		this.debugOut("Incomming failure for id " + activityId + " and model id " + id);
		this.log("dbFailed: " + inEvent.message);
		this.setDbActivities(this.dbActivities - 1);
		enyo.Signals.send("onArticleOpReturned", {
			id: id,
			success: false,
			method: method,
			activityId: activityId
		});
		this.sendNext(id, method);
		if (typeof callback === "function") {
			callback(inEvent);
		}
	}
});


"gvar_changename pr1 xs = map (%x. case x of GV a b => GV a (fst pr1 @ b)) xs"
by the above, I was able to describe a definition without a problem.
However, in proof, a problem happened.
"(distinct (Prog_GvarList pr2)) ==> (distinct (gvar_changename pr2 (Prog_GvarList pr2)))"
"case" emerged in subgoal, and proof did not advance.
I think that I asked you a question many times that I am sorry, but please instruct it.
type_synonym str = "char list"
type_synonym GvarList = "Gvar list"
type_synonym Prog = "(FileName * GvarList * Funcs * Main)"
"Funcs" and "Main" , define it at other places, but do not use it here.


text:
HomeEthereumEthereum faces largest ever options expiry as bears appear to dominate
Ethereum faces largest ever options expiry as bears appear to dominate
June 21, 2021 CryptoExpert Ethereum
Ether (ETH) faces its largest options expiry ever on June 25 as nearly $1.5 billion out of $3.3 billion notional open interest (OI) in ETH options will expire. June's expiry has over 638,000 ETH options contracts in its purview, accounting for 45% of the total open interest in these options.
Although it's the largest options expiry in the history of the derivative product, the open interest in ETH options OI hit its all-time high of nearly $5.5 billion on May 20 soon after ETH had hit its all-time high of $4,362 on May 12.
The huge expiry amid the ongoing market-wide pull is indicative of increased interest in the ETH derivatives market despite the token trading in the $2,270 range, 47.61% lower than its all-time high from mid-May. Luuk Strijers, chief commercial officer of crypto derivatives exchange Deribit, told Cointelegraph:
"The put call ratio for the June expiry is 0.79, which indicates there are more calls outstanding versus puts (64,000 more). This is indeed indicative for bullish sentiment, however, the majority of this OI is held in contracts quite far away from the current ETH price, indicating a low likelihood of expiring in the money."
Although, Robbie Liu, analyst at the Market Insights team of OKEx — a cryptocurrency exchange — pointed out what this gap in price indicates, "The expiry is still dominated by the bears since a significant amount of call options are a long way off the current price. For example, the largest OI is concentrated in strikes at the mark of $3,200 for call options."
Call options contracts allow holders to buy Ether at a predetermined price on the date of expiry, while put options contracts allow them to sell Ether under similar pre-requisites. Under usual circumstances, call options are used to supplement bullish strategies, while put options are utilized as hedges against negative price movements of the underlying.
The max pain price for this record expiry is $1,920. This price being the point where the largest number of options are at a loss, it is highly unlikely that the price of ETH will drop more than 10% from its current trading range. Although, as witnessed on May 19, a day now more commonly known as Black Wednesday in the cryptoverse, seasoned investors would never say never.
Strijers further explained the impact of the growing open interest in terms of the number of contracts: "Due to the growing size of our open interest pool, we notice our options expiries are becoming more and more important liquidity and risk transfer events creating a virtuous circle."
He also added that even though the notional open interest of the ETH options has decreased in terms of United States dollar value due to the decline in the spot price, the open interest measured in contracts has barely been impacted by the price drop. This indicates the sustained interest in the Ether derivatives market despite the price slump.
CME data shows rising institutional demand
The Chicago Mercantile Exchange, the world's largest derivatives exchange, launched its Ether futures product on Feb. 8 earlier this year. The highly anticipated launch witnessed more than $30 million of volume on the first day of trading on the exchange.
According to a report by OKEx, the launch of CME Ether Futures comes as a "nod of approval" from the most widely used exchange for derivatives products. Richard Delany, a senior analyst from the OKEx Insights team, opined further that, "This does indeed appear to have attracted significant institutional interest to the number two cryptocurrency."
However, Delany also pointed out that market conditions and context surrounding the launch are quite different when compared to the launch of CME's Bitcoin Futures in December 2017. The launch of the CME's Bitcoin (BTC) futures came during an extended bear market when interest in digital currencies had waned across the board, and the product provided exposure to the flagship cryptocurrency for institutions unable to access channels available for retail investors. Delany added:
"In the more than three years since CME BTC futures launched, familiarity with such crypto trading instruments has proliferated, leading to massive growth in both CME BTC futures and their newer ETH counterparts. Despite the recent market correction, interest in cryptocurrency generally remains much greater than in early 2018."
According to data provided to Cointelegraph by the CME, its Ether futures contract had an average daily volume (ADV) in May of 5,895 contracts, and the average open interest in May is 3,082, which is equivalent to $6.86 million in notional value.
The record trading day for the CME Ether futures contract was on May 19, which amounted to a total of 11,980 contracts, or $26.5 million worth of options. The record for open interest of 3,977 contracts came through on June 1, equivalent to $8.82 million at the current market price of the token.
The large open interest holders (LOIH) in this derivatives contract also hit a high of 45 on May 25, with the average for May being 37 LOIHs. Each LOIH holds at least 25 futures contracts, which are equivalent to 1,250 ETH or $2.7 million in notional value at least at the time of writing. However, Strijers explained why this growth was limited, "CME has realized around $400 million in ETH open interest. Growth of this amount is somewhat limited due to the lack of current yield, which was a big driver for CME volumes."
However, the spokesperson from CME also mentioned that currently, it doesn't have a plan to include additional cryptocurrency products like Ether options in their product suite, which includes Bitcoin and Micro Bitcoin futures, Bitcoin options and Ether futures.
Correlation between BTC and ETH
Ether's correlation with Bitcoin saw a drop in early May to the sub 0.6 levels due to completely independent price movements that Ether made during that period. The one-month correlation was between 0.7 and 0.8 in April before dropping to 0.5–0.6 in early May, but it rebounded drastically to 0.9 in early June, holding high levels since.
BTC/ETH 30-day correlation
However, in the recent BTC rally to $41,000, ETH showed rather limited price movement, consistently trading in the $2,400–2,500 range throughout the rally, which was driven by the news of El Salvador becoming the first country to accept Bitcoin as legal tender. Liu pointed out, "In the recent past, the rebound of ETH has not gained as much momentum as BTC, with the price of ETH/BTC having fallen 20% since its June 7 high."
Related: An asset for all classes: What to expect from Bitcoin as a legal tender
Since the positive price trend for BTC before May 16, Bitcoin has been steadily dropping to around the $35,500 mark, dragging ETH along with it to trade in the $2,200 range, which amounted to a 6% drop in 24 hours. Liu mentioned why ETH could take longer to rebound from the ongoing price slump than BTC:
"If we look back to the beginning of 2018, ETH likewise set its all-time high price a month after BTC topped out. And then ETH/BTC experienced a two-month decline before the trend reversed. It will take longer for the market to reverse ETH's momentum."
However, for the Ethereum network, June brought in improvement in one important aspect: gas fees. The network transaction fees for both Bitcoin and Ethereum hit a six-month low on June 1.
This change occurred in June, nearly two months after the Berlin hard fork took place on April 13, which was the initial step that the network is taking toward addressing the highly concerning gas fee issue that has been plaguing the network for a long time. Liu opined further:
"The constant high gas fees in March and April were clearly a major reason for the transfer of funds to EVMs and sidechains, which led to the total value locked in BSC surging. Also, in the mid-May sell-off, Ethereum gas fees spiking above 1,000 gwei caused DeFi participants to start moving to Polygon."
Even though the lower gas fees can be purely a result of lesser transactions and congestion in the network rather than a scalability fix to the network, it still brings much-needed relief to investors and decentralized finance users alike.
As the price momentum in the top two cryptocurrencies continues to drop, it will be interesting to observe the changes that this $1.5-billion bear-dominated expiry will bring for the Ethereum network and the price of its token.
How smart regulation can improve the future of blockchain
The Use of T.A Could Make Bitcoin's Death Cross Self-fulfilling
Binance Bitcoin blockchain BTC Coinbase Cointelegraph crypto DeFi Digest DOGE Dogecoin Ethereum hits Hodlers July launches Litecoin LTC Magazine metaverse NFTs Powers price Questions SEC

redpajama_set_name: RedPajamaCommonCrawl


text:
namespace Factotum
{
	partial class StatusReport
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			Microsoft.Reporting.WinForms.ReportDataSource reportDataSource1 = new Microsoft.Reporting.WinForms.ReportDataSource();
			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(StatusReport));
			this.TmpStatusReportBindingSource = new System.Windows.Forms.BindingSource(this.components);
			this.StatusReportDataSet = new Factotum.StatusReportDataSet();
			this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer();
			this.rvStatusReport = new Microsoft.Reporting.WinForms.ReportViewer();
			this.toolStrip1 = new System.Windows.Forms.ToolStrip();
			this.btnReportSubmitted = new System.Windows.Forms.ToolStripButton();
			this.btnUtComplete = new System.Windows.Forms.ToolStripButton();
			this.btnCurrentView = new System.Windows.Forms.ToolStripButton();
			this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
			this.btnIncludePrevReported = new System.Windows.Forms.ToolStripButton();
			this.TmpStatusReportTableAdapter = new Factotum.StatusReportDataSetTableAdapters.TmpStatusReportTableAdapter();
			((System.ComponentModel.ISupportInitialize)(this.TmpStatusReportBindingSource)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.StatusReportDataSet)).BeginInit();
			this.toolStripContainer1.ContentPanel.SuspendLayout();
			this.toolStripContainer1.TopToolStripPanel.SuspendLayout();
			this.toolStripContainer1.SuspendLayout();
			this.toolStrip1.SuspendLayout();
			this.SuspendLayout();
			//
			// TmpStatusReportBindingSource
			//
			this.TmpStatusReportBindingSource.DataMember = "TmpStatusReport";
			this.TmpStatusReportBindingSource.DataSource = this.StatusReportDataSet;
			//
			// StatusReportDataSet
			//
			this.StatusReportDataSet.DataSetName = "StatusReportDataSet";
			this.StatusReportDataSet.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema;
			//
			// toolStripContainer1
			//
			this.toolStripContainer1.BottomToolStripPanelVisible = false;
			//
			// toolStripContainer1.ContentPanel
			//
			this.toolStripContainer1.ContentPanel.AutoScroll = true;
			this.toolStripContainer1.ContentPanel.Controls.Add(this.rvStatusReport);
			this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(745, 292);
			this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
			this.toolStripContainer1.LeftToolStripPanelVisible = false;
			this.toolStripContainer1.Location = new System.Drawing.Point(0, 0);
			this.toolStripContainer1.Name = "toolStripContainer1";
			this.toolStripContainer1.RightToolStripPanelVisible = false;
			this.toolStripContainer1.Size = new System.Drawing.Size(745, 317);
			this.toolStripContainer1.TabIndex = 1;
			this.toolStripContainer1.Text = "toolStripContainer1";
			//
			// toolStripContainer1.TopToolStripPanel
			//
			this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.toolStrip1);
			//
			// rvStatusReport
			//
			this.rvStatusReport.Dock = System.Windows.Forms.DockStyle.Fill;
			reportDataSource1.Name = "StatusReportDataSet_TmpStatusReport";
			reportDataSource1.Value = this.TmpStatusReportBindingSource;
			this.rvStatusReport.LocalReport.DataSources.Add(reportDataSource1);
			this.rvStatusReport.LocalReport.ReportEmbeddedResource = "Factotum.StatusReport.rdlc";
			this.rvStatusReport.Location = new System.Drawing.Point(0, 0);
			this.rvStatusReport.Name = "rvStatusReport";
			this.rvStatusReport.Size = new System.Drawing.Size(745, 292);
			this.rvStatusReport.TabIndex = 0;
			//
			// toolStrip1
			//
			this.toolStrip1.Dock = System.Windows.Forms.DockStyle.None;
			this.toolStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
			this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.btnReportSubmitted,
            this.btnUtComplete,
            this.btnCurrentView,
            this.toolStripSeparator1,
            this.btnIncludePrevReported});
			this.toolStrip1.Location = new System.Drawing.Point(3, 0);
			this.toolStrip1.Name = "toolStrip1";
			this.toolStrip1.Size = new System.Drawing.Size(478, 25);
			this.toolStrip1.TabIndex = 0;
			//
			// btnReportSubmitted
			//
			this.btnReportSubmitted.Checked = true;
			this.btnReportSubmitted.CheckState = System.Windows.Forms.CheckState.Checked;
			this.btnReportSubmitted.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
			this.btnReportSubmitted.Image = ((System.Drawing.Image)(resources.GetObject("btnReportSubmitted.Image")));
			this.btnReportSubmitted.ImageTransparentColor = System.Drawing.Color.Magenta;
			this.btnReportSubmitted.Name = "btnReportSubmitted";
			this.btnReportSubmitted.Size = new System.Drawing.Size(153, 22);
			this.btnReportSubmitted.Text = "Component Report Submitted";
			this.btnReportSubmitted.Click += new System.EventHandler(this.btnReportSubmitted_Click);
			//
			// btnUtComplete
			//
			this.btnUtComplete.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
			this.btnUtComplete.Image = ((System.Drawing.Image)(resources.GetObject("btnUtComplete.Image")));
			this.btnUtComplete.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
			this.btnUtComplete.ImageTransparentColor = System.Drawing.Color.Magenta;
			this.btnUtComplete.Name = "btnUtComplete";
			this.btnUtComplete.Size = new System.Drawing.Size(97, 22);
			this.btnUtComplete.Text = "UT Field Complete";
			this.btnUtComplete.Click += new System.EventHandler(this.btnUtComplete_Click);
			//
			// btnCurrentView
			//
			this.btnCurrentView.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
			this.btnCurrentView.Image = ((System.Drawing.Image)(resources.GetObject("btnCurrentView.Image")));
			this.btnCurrentView.ImageTransparentColor = System.Drawing.Color.Magenta;
			this.btnCurrentView.Name = "btnCurrentView";
			this.btnCurrentView.Size = new System.Drawing.Size(73, 22);
			this.btnCurrentView.Text = "Current View";
			this.btnCurrentView.Click += new System.EventHandler(this.btnCurrentView_Click);
			//
			// toolStripSeparator1
			//
			this.toolStripSeparator1.Name = "toolStripSeparator1";
			this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
			//
			// btnIncludePrevReported
			//
			this.btnIncludePrevReported.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
			this.btnIncludePrevReported.Image = ((System.Drawing.Image)(resources.GetObject("btnIncludePrevReported.Image")));
			this.btnIncludePrevReported.ImageTransparentColor = System.Drawing.Color.Magenta;
			this.btnIncludePrevReported.Name = "btnIncludePrevReported";
			this.btnIncludePrevReported.Size = new System.Drawing.Size(146, 22);
			this.btnIncludePrevReported.Text = "Include Previously Reported";
			this.btnIncludePrevReported.Click += new System.EventHandler(this.btnIncludePrevReported_Click);
			//
			// TmpStatusReportTableAdapter
			//
			this.TmpStatusReportTableAdapter.ClearBeforeFill = true;
			//
			// StatusReport
			//
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(745, 317);
			this.Controls.Add(this.toolStripContainer1);
			this.MinimumSize = new System.Drawing.Size(518, 132);
			this.Name = "StatusReport";
			this.Text = "StatusReport";
			this.Load += new System.EventHandler(this.StatusReport_Load);
			((System.ComponentModel.ISupportInitialize)(this.TmpStatusReportBindingSource)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.StatusReportDataSet)).EndInit();
			this.toolStripContainer1.ContentPanel.ResumeLayout(false);
			this.toolStripContainer1.TopToolStripPanel.ResumeLayout(false);
			this.toolStripContainer1.TopToolStripPanel.PerformLayout();
			this.toolStripContainer1.ResumeLayout(false);
			this.toolStripContainer1.PerformLayout();
			this.toolStrip1.ResumeLayout(false);
			this.toolStrip1.PerformLayout();
			this.ResumeLayout(false);

		}

		#endregion

		private System.Windows.Forms.ToolStripContainer toolStripContainer1;
		private System.Windows.Forms.ToolStrip toolStrip1;
		private System.Windows.Forms.ToolStripButton btnUtComplete;
		private System.Windows.Forms.ToolStripButton btnReportSubmitted;
		private System.Windows.Forms.ToolStripButton btnCurrentView;
		private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
		private System.Windows.Forms.ToolStripButton btnIncludePrevReported;
		private Microsoft.Reporting.WinForms.ReportViewer rvStatusReport;
		private System.Windows.Forms.BindingSource TmpStatusReportBindingSource;
		private StatusReportDataSet StatusReportDataSet;
		private Factotum.StatusReportDataSetTableAdapters.TmpStatusReportTableAdapter TmpStatusReportTableAdapter;
	}
}