package main import ( "testing" ) func TestParseBasicCommand(t *testing.T) { sf, err := parse("test.shout", "$ echo hello\nhello\n") if err != nil { t.Fatal(err) } if len(sf.Commands) != 1 { t.Fatalf("expected 1 command, got %d", len(sf.Commands)) } c := sf.Commands[0] if c.Cmd != "echo hello" { t.Errorf("cmd = %q, want %q", c.Cmd, "echo hello") } if len(c.Expected) != 1 || c.Expected[0] != "hello" { t.Errorf("expected = %v, want [hello]", c.Expected) } if c.ExitCodeType != ExitCodeNone { t.Errorf("exit code type = %d, want ExitCodeNone", c.ExitCodeType) } } func TestParseMultipleCommands(t *testing.T) { sf, err := parse("test.shout", "$ echo one\none\n\n$ echo two\ntwo\n") if err != nil { t.Fatal(err) } if len(sf.Commands) != 2 { t.Fatalf("expected 2 commands, got %d", len(sf.Commands)) } if sf.Commands[0].Cmd != "echo one" { t.Errorf("cmd[0] = %q", sf.Commands[0].Cmd) } if sf.Commands[1].Cmd != "echo two" { t.Errorf("cmd[1] = %q", sf.Commands[1].Cmd) } } func TestParseExitCode(t *testing.T) { sf, err := parse("test.shout", "$ false\n[1]\n") if err != nil { t.Fatal(err) } c := sf.Commands[0] if c.ExitCodeType != ExitCodeExact || c.ExitCodeValue != 1 { t.Errorf("exit code = (%d, %d), want (Exact, 1)", c.ExitCodeType, c.ExitCodeValue) } if len(c.Expected) != 0 { t.Errorf("expected = %v, want []", c.Expected) } } func TestParseExitCodeWildcard(t *testing.T) { sf, err := parse("test.shout", "$ false\n[*]\n") if err != nil { t.Fatal(err) } c := sf.Commands[0] if c.ExitCodeType != ExitCodeWildcard { t.Errorf("exit code type = %d, want Wildcard", c.ExitCodeType) } } func TestParseExitCodeWithOutput(t *testing.T) { sf, err := parse("test.shout", "$ sh -c \"echo oops && exit 1\"\noops\n[*]\n") if err != nil { t.Fatal(err) } c := sf.Commands[0] if len(c.Expected) != 1 || c.Expected[0] != "oops" { t.Errorf("expected = %v, want [oops]", c.Expected) } if c.ExitCodeType != ExitCodeWildcard { t.Errorf("exit code type = %d, want Wildcard", c.ExitCodeType) } } func TestParseComment(t *testing.T) { sf, err := parse("test.shout", "$ echo hello # this is a comment\nhello\n") if err != nil { t.Fatal(err) } if sf.Commands[0].Cmd != "echo hello" { t.Errorf("cmd = %q, want %q", sf.Commands[0].Cmd, "echo hello") } } func TestParseCommentInQuotes(t *testing.T) { sf, err := parse("test.shout", "$ echo \"keep # this\"\nkeep # this\n") if err != nil { t.Fatal(err) } if sf.Commands[0].Cmd != `echo "keep # this"` { t.Errorf("cmd = %q", sf.Commands[0].Cmd) } } func TestParseEnvDirective(t *testing.T) { sf, err := parse("test.shout", "@env GREETING=hello\n\n$ echo $GREETING\nhello\n") if err != nil { t.Fatal(err) } if len(sf.Directives) != 1 { t.Fatalf("expected 1 directive, got %d", len(sf.Directives)) } d := sf.Directives[0] if d.Type != "env" || d.Key != "GREETING" || d.Value != "hello" { t.Errorf("directive = %+v", d) } } func TestParseSetupDirective(t *testing.T) { sf, err := parse("test.shout", "@setup shared.shout\n\n$ echo hi\nhi\n") if err != nil { t.Fatal(err) } if len(sf.Directives) != 1 { t.Fatalf("expected 1 directive, got %d", len(sf.Directives)) } d := sf.Directives[0] if d.Type != "setup" || d.Path != "shared.shout" { t.Errorf("directive = %+v", d) } } func TestParseNoExpectedOutput(t *testing.T) { sf, err := parse("test.shout", "$ export FOO=bar\n$ echo $FOO\nbar\n") if err != nil { t.Fatal(err) } if len(sf.Commands) != 2 { t.Fatalf("expected 2 commands, got %d", len(sf.Commands)) } if len(sf.Commands[0].Expected) != 0 { t.Errorf("first command expected = %v, want []", sf.Commands[0].Expected) } } func TestParseTrimsTrailingBlanks(t *testing.T) { sf, err := parse("test.shout", "$ echo hello\nhello\n\n\n$ echo world\nworld\n") if err != nil { t.Fatal(err) } if len(sf.Commands[0].Expected) != 1 || sf.Commands[0].Expected[0] != "hello" { t.Errorf("expected = %v", sf.Commands[0].Expected) } } func TestParseLineNumbers(t *testing.T) { sf, err := parse("test.shout", "@env X=1\n\n$ echo hello\nhello\n\n$ echo world\nworld\n") if err != nil { t.Fatal(err) } if sf.Directives[0].Line != 1 { t.Errorf("directive line = %d, want 1", sf.Directives[0].Line) } if sf.Commands[0].Line != 3 { t.Errorf("command[0] line = %d, want 3", sf.Commands[0].Line) } if sf.Commands[1].Line != 6 { t.Errorf("command[1] line = %d, want 6", sf.Commands[1].Line) } }