11package commands
22
33import (
4+ "encoding/json"
45 "errors"
56 "fmt"
67 "io"
@@ -18,7 +19,7 @@ import (
1819func newFakeKoolRun (mockParsedCommands map [string ][]builder.Command , mockParseError map [string ]error ) * KoolRun {
1920 return & KoolRun {
2021 * (newDefaultKoolService ().Fake ()),
21- & KoolRunFlags {[]string {}},
22+ & KoolRunFlags {[]string {}, false },
2223 & parser.FakeParser {MockParsedCommands : mockParsedCommands , MockParseError : mockParseError },
2324 environment .NewFakeEnvStorage (),
2425 & shell.FakePromptSelect {},
@@ -745,3 +746,107 @@ func TestNewRunCommandWithTypoErrorCancelled(t *testing.T) {
745746 t .Errorf ("expecting warning '%s', got '%s'" , expected , output )
746747 }
747748}
749+
750+ func TestNewRunCommandJsonOutput (t * testing.T ) {
751+ f := newFakeKoolRun (nil , nil )
752+ f .parser .(* parser.FakeParser ).MockScriptDetails = []parser.ScriptDetail {
753+ {
754+ Name : "setup" ,
755+ Comments : []string {"Sets up dependencies" },
756+ Commands : []string {"kool run composer install" },
757+ },
758+ {
759+ Name : "lint" ,
760+ Comments : []string {},
761+ Commands : []string {"kool run go:linux fmt ./..." },
762+ },
763+ }
764+
765+ cmd := NewRunCommand (f )
766+ cmd .SetArgs ([]string {"--json" })
767+
768+ if err := cmd .Execute (); err != nil {
769+ t .Errorf ("unexpected error executing run command with --json; error: %v" , err )
770+ }
771+
772+ if ! f .parser .(* parser.FakeParser ).CalledParseAvailableDetails {
773+ t .Error ("did not call ParseAvailableScriptsDetails" )
774+ }
775+
776+ fakeShell := f .shell .(* shell.FakeShell )
777+
778+ if len (fakeShell .OutLines ) == 0 {
779+ t .Error ("expected JSON output" )
780+ return
781+ }
782+
783+ var output []parser.ScriptDetail
784+ if err := json .Unmarshal ([]byte (fakeShell .OutLines [0 ]), & output ); err != nil {
785+ t .Fatalf ("failed to parse json output: %v" , err )
786+ }
787+
788+ if len (output ) != 2 {
789+ t .Fatalf ("expected 2 script entries, got %d" , len (output ))
790+ }
791+
792+ if output [0 ].Name != "lint" || output [1 ].Name != "setup" {
793+ t .Errorf ("unexpected scripts order or names: %v" , output )
794+ }
795+ }
796+
797+ func TestNewRunCommandJsonOutputEmpty (t * testing.T ) {
798+ f := newFakeKoolRun (nil , nil )
799+ f .parser .(* parser.FakeParser ).MockScriptDetails = []parser.ScriptDetail {}
800+
801+ cmd := NewRunCommand (f )
802+ cmd .SetArgs ([]string {"--json" })
803+
804+ if err := cmd .Execute (); err != nil {
805+ t .Errorf ("unexpected error executing run command with --json; error: %v" , err )
806+ }
807+
808+ fakeShell := f .shell .(* shell.FakeShell )
809+
810+ if len (fakeShell .OutLines ) == 0 {
811+ t .Error ("expected JSON output" )
812+ return
813+ }
814+
815+ // Should output empty array, not null
816+ if fakeShell .OutLines [0 ] != "[]" {
817+ t .Errorf ("expected empty JSON array '[]', got '%s'" , fakeShell .OutLines [0 ])
818+ }
819+ }
820+
821+ func TestNewRunCommandJsonOutputNullSafety (t * testing.T ) {
822+ f := newFakeKoolRun (nil , nil )
823+ f .parser .(* parser.FakeParser ).MockScriptDetails = []parser.ScriptDetail {
824+ {
825+ Name : "test" ,
826+ Comments : nil , // nil comments
827+ Commands : nil , // nil commands
828+ },
829+ }
830+
831+ cmd := NewRunCommand (f )
832+ cmd .SetArgs ([]string {"--json" })
833+
834+ if err := cmd .Execute (); err != nil {
835+ t .Errorf ("unexpected error executing run command with --json; error: %v" , err )
836+ }
837+
838+ fakeShell := f .shell .(* shell.FakeShell )
839+
840+ var output []parser.ScriptDetail
841+ if err := json .Unmarshal ([]byte (fakeShell .OutLines [0 ]), & output ); err != nil {
842+ t .Fatalf ("failed to parse json output: %v" , err )
843+ }
844+
845+ // Verify nil values are converted to empty arrays
846+ if output [0 ].Comments == nil {
847+ t .Error ("Comments should not be nil in JSON output" )
848+ }
849+ if output [0 ].Commands == nil {
850+ t .Error ("Commands should not be nil in JSON output" )
851+ }
852+ }
0 commit comments