diff --git a/go.mod b/go.mod index 34572dd44..6b3f976a0 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/manifoldco/promptui v0.9.0 github.com/onflow/cadence v0.42.5 github.com/onflow/cadence-tools/languageserver v0.33.3 - github.com/onflow/cadence-tools/test v0.14.3 + github.com/onflow/cadence-tools/test v0.14.4 github.com/onflow/fcl-dev-wallet v0.7.4 github.com/onflow/flixkit-go v0.3.1 github.com/onflow/flow-cli/flowkit v1.6.1-0.20231110211255-b41f57a8b8c7 diff --git a/go.sum b/go.sum index 795c05c49..9cf9f0efe 100644 --- a/go.sum +++ b/go.sum @@ -880,8 +880,8 @@ github.com/onflow/cadence-tools/languageserver v0.33.3 h1:o6f2kPxsgSruH+HT8CakcZ github.com/onflow/cadence-tools/languageserver v0.33.3/go.mod h1:rUy3zxWWZl+KYAyzhAcnrYNI8ZDKI242RFK8Q9w+90M= github.com/onflow/cadence-tools/lint v0.14.1 h1:Qkw8+q+ALfB62W7KWHMFh+90gTfJ+NoFulYETMCTkcI= github.com/onflow/cadence-tools/lint v0.14.1/go.mod h1:w1xfiiPpZ35v/F+2+MF/Rily7LcIgE0dm/FMW1vQkpc= -github.com/onflow/cadence-tools/test v0.14.3 h1:tpLn7hBXij7QSSSUH3Pr7Fkl0jMoOSmmgj2ynK71Dyw= -github.com/onflow/cadence-tools/test v0.14.3/go.mod h1:1FaKl2BPM05BWWwo5ctwE7dA/CE5KA/kxUrtcCkvCEc= +github.com/onflow/cadence-tools/test v0.14.4 h1:m4SwQFbzHasCDiLdI0zNIZVRMLYQUfiiL6BDZSp06Jo= +github.com/onflow/cadence-tools/test v0.14.4/go.mod h1:1FaKl2BPM05BWWwo5ctwE7dA/CE5KA/kxUrtcCkvCEc= github.com/onflow/fcl-dev-wallet v0.7.4 h1:vI6t3U0AO88R/Iitn5KsnniSpbN9Lqsqwvi9EJT4C0k= github.com/onflow/fcl-dev-wallet v0.7.4/go.mod h1:kc42jkiuoPJmxMRFjfbRO9XvnR/3XLheaOerxVMDTiw= github.com/onflow/flixkit-go v0.3.1 h1:5izElx+3H7vCqlzK0pzEZ+lW3xjfLoB4w5cD2/3qe2M= diff --git a/internal/test/test.go b/internal/test/test.go index a94ded9a0..a24dc7b98 100644 --- a/internal/test/test.go +++ b/internal/test/test.go @@ -65,6 +65,7 @@ type flagsTests struct { CoverCode string `default:"all" flag:"covercode" info:"Use the covercode flag to calculate coverage report only for certain types of code. Available values are \"all\" & \"contracts\""` Random bool `default:"false" flag:"random" info:"Use the random flag to execute test cases randomly"` Seed int64 `default:"0" flag:"seed" info:"Use the seed flag to manipulate random execution of test cases"` + Name string `default:"" flag:"name" info:"Use the name flag to run only tests that match the given name"` } var testFlags = flagsTests{} @@ -191,13 +192,32 @@ func testCode( WithFileResolver(fileResolver(scriptPath, state)). WithContracts(contracts) - results, err := runner.RunTests(string(code)) - if err != nil { - return nil, err + if flags.Name != "" { + testFunctions, err := runner.GetTests(string(code)) + if err != nil { + return nil, err + } + + for _, testFunction := range testFunctions { + if testFunction != flags.Name { + continue + } + + result, err := runner.RunTest(string(code), flags.Name) + if err != nil { + return nil, err + } + testResults[scriptPath] = []cdcTests.Result{*result} + } + } else { + results, err := runner.RunTests(string(code)) + if err != nil { + return nil, err + } + testResults[scriptPath] = results } - testResults[scriptPath] = results - for _, result := range results { + for _, result := range testResults[scriptPath] { if result.Error != nil { status = 1 break @@ -337,6 +357,11 @@ func (r *result) String() string { func (r *result) Oneliner() string { var builder strings.Builder + if len(r.Results) == 0 { + builder.WriteString("No tests found") + return builder.String() + } + for scriptPath, testResult := range r.Results { builder.WriteString(cdcTests.PrettyPrintResults(testResult, scriptPath)) } diff --git a/internal/test/test_test.go b/internal/test/test_test.go index 1d2dc1554..29d70f55c 100644 --- a/internal/test/test_test.go +++ b/internal/test/test_test.go @@ -585,4 +585,91 @@ Seed: 1521 string(output), ) }) + + t.Run("run specific test case by name", func(t *testing.T) { + t.Parallel() + + // Setup + _, state, _ := util.TestMocks(t) + + // Execute script + script := tests.TestScriptSimple + testFiles := map[string][]byte{ + script.Filename: script.Source, + } + flags := flagsTests{ + Name: "testSimple", + } + + result, err := testCode(testFiles, state, flags) + + assert.NoError(t, err) + assert.Len(t, result.Results, 1) + assert.NoError(t, result.Results[script.Filename][0].Error) + + expected := "Test results: \"./testScriptSimple.cdc\"\n- PASS: testSimple\n" + assert.Equal( + t, + expected, + result.Oneliner(), + ) + }) + + t.Run("run specific test case by name multiple files", func(t *testing.T) { + t.Parallel() + + // Setup + _, state, _ := util.TestMocks(t) + + scriptPassing := tests.TestScriptSimple + scriptFailing := tests.TestScriptSimpleFailing + + // Execute script + testFiles := map[string][]byte{ + scriptPassing.Filename: scriptPassing.Source, + scriptFailing.Filename: scriptFailing.Source, + } + flags := flagsTests{ + Name: "testSimple", + } + + result, err := testCode(testFiles, state, flags) + + assert.NoError(t, err) + assert.Len(t, result.Results, 2) + assert.NoError(t, result.Results[scriptPassing.Filename][0].Error) + assert.Error(t, result.Results[scriptFailing.Filename][0].Error) + assert.ErrorAs(t, result.Results[scriptFailing.Filename][0].Error, &stdlib.AssertionError{}) + assert.Equal( + t, + "Test results: \"./testScriptSimple.cdc\"\n- PASS: testSimple\nTest results: \"./testScriptSimpleFailing.cdc\"\n- FAIL: testSimple\n\t\tExecution failed:\n\t\t\terror: assertion failed\n\t\t\t --> 7465737400000000000000000000000000000000000000000000000000000000:5:12\n\t\t\t\n", + result.Oneliner(), + ) + }) + + t.Run("run specific test case by name will do nothing if not found", func(t *testing.T) { + t.Parallel() + + // Setup + _, state, _ := util.TestMocks(t) + + // Execute script + script := tests.TestScriptSimple + testFiles := map[string][]byte{ + script.Filename: script.Source, + } + flags := flagsTests{ + Name: "doesNotExist", + } + + result, err := testCode(testFiles, state, flags) + + assert.NoError(t, err) + assert.Len(t, result.Results, 0) + assert.Equal( + t, + "No tests found", + result.Oneliner(), + ) + }) }