From 28304131f8758d181e857b48ec50c0179f10a47a Mon Sep 17 00:00:00 2001 From: "meo.con.batu" Date: Sat, 8 Jul 2023 23:41:12 +0800 Subject: [PATCH 1/3] Test code extraction for exercises with separate file for test cases This commit also support arbitrary test data variable name when test function includes multiple assignments. --- go.mod | 2 +- go.sum | 2 +- testrunner/ast.go | 117 ++++++++++++++---- testrunner/extract.go | 2 +- testrunner/extract_test.go | 107 ++++++++++++++++ .../concept/conditionals/cases_test.go | 59 +++++++++ .../concept/conditionals/conditionals_test.go | 68 ++++++++++ 7 files changed, 327 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index db788b7..0194d5b 100644 --- a/go.mod +++ b/go.mod @@ -7,4 +7,4 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/stretchr/testify v1.8.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect -) +) \ No newline at end of file diff --git a/go.sum b/go.sum index 658c3d6..6c8356a 100644 --- a/go.sum +++ b/go.sum @@ -13,4 +13,4 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= \ No newline at end of file diff --git a/testrunner/ast.go b/testrunner/ast.go index 46ed919..ffc2f14 100644 --- a/testrunner/ast.go +++ b/testrunner/ast.go @@ -3,12 +3,14 @@ package testrunner import ( "bytes" "errors" + "fmt" "go/ast" "go/format" "go/parser" "go/printer" "go/token" "log" + "path/filepath" "regexp" "strconv" "strings" @@ -34,6 +36,7 @@ type rootLevelTest struct { fileName string code string taskID uint64 + pkgName string } // FindAllRootLevelTests parses the test file and extracts the name, @@ -60,6 +63,7 @@ func FindAllRootLevelTests(fileName string) []rootLevelTest { fileName: fileName, code: buf.String(), taskID: taskID, + pkgName: file.Name.Name, }) } } @@ -95,16 +99,19 @@ func findTaskID(doc *ast.CommentGroup) uint64 { } // generate simplified test code corresponding to a subtest -func getSubCode(test string, sub string, code string, file string) string { +func getSubCode(test string, sub string, code string, file string, pkgName string) string { + pkgLine := fmt.Sprintf("package %s\n", pkgName) fset := token.NewFileSet() f, err := parser.ParseFile( - fset, file, "package main\n"+code, parser.ParseComments, + fset, file, pkgLine+code, parser.ParseComments, ) if err != nil { log.Printf("warning: '%s' not parsed from '%s': %s", test, file, err) return "" } + resolveTestData(fset, f, file) + fAST, ok := f.Decls[0].(*ast.FuncDecl) if !ok { log.Println("warning: first subtest declaration must be a function") @@ -113,7 +120,7 @@ func getSubCode(test string, sub string, code string, file string) string { fbAST := fAST.Body.List // f.Decls[0].Body.List - astInfo, err := findTestDataAndRange(fbAST) + astInfo, err := findTestDataAndRange(fbAST, fset) if err != nil { log.Printf("warning: could not find test table and/or range: %v\n", err) return "" @@ -146,36 +153,33 @@ func getSubCode(test string, sub string, code string, file string) string { log.Println("warning: failed to format extracted AST for subtest") return "" } - return strings.TrimSpace(strings.TrimPrefix(buf.String(), "package main")) + if astInfo.testDataAstIdx != -1 { // testDataAst is already in the test function + return strings.TrimSpace(strings.TrimPrefix(buf.String(), pkgLine)) + } + return insertTestDataASTIntoFunc(fset, astInfo.testDataAst, fAST.Body, buf.Bytes(), pkgLine) } -func findTestDataAndRange(stmtList []ast.Stmt) (subTestAstInfo, error) { +func findTestDataAndRange(stmtList []ast.Stmt, fset *token.FileSet) (subTestAstInfo, error) { result := subTestAstInfo{} - + posToIndex := make(map[token.Position]int) for i := range stmtList { - assignCandidate, ok := stmtList[i].(*ast.AssignStmt) - if ok && result.testDataAst == nil { - result.testDataAst = assignCandidate - result.testDataAstIdx = i - } else if ok { - identifier, isIdentifier := assignCandidate.Lhs[0].(*ast.Ident) - if !isIdentifier { - continue - } - // Overwrite the assignment we already found in case there is an - // assignment to a "tests" variable. - if identifier.Name == "tests" { + posToIndex[fset.Position(stmtList[i].Pos())] = i + if rangeCandidate, ok := stmtList[i].(*ast.RangeStmt); ok { + assignCandidate := getTestDataAssignFromRange(rangeCandidate) + if assignCandidate != nil { + // check if assignCandidate is in the same function with rangeCandidate + if idx, ok := posToIndex[fset.Position(assignCandidate.Pos())]; ok && + fset.File(assignCandidate.Pos()).Name() == fset.File(rangeCandidate.Pos()).Name() { + result.testDataAstIdx = idx + } else { + result.testDataAstIdx = -1 + } result.testDataAst = assignCandidate - result.testDataAstIdx = i + result.rangeAst = rangeCandidate + result.rangeAstIdx = i + return result, nil } - } - - rangeCandidate, ok := stmtList[i].(*ast.RangeStmt) - // If we found a range after we already found an assignment, we are good to go. - if ok && result.testDataAst != nil { - result.rangeAst = rangeCandidate - result.rangeAstIdx = i - return result, nil + return subTestAstInfo{}, errors.New("failed to find assignment in sub-test") } } @@ -185,6 +189,24 @@ func findTestDataAndRange(stmtList []ast.Stmt) (subTestAstInfo, error) { return subTestAstInfo{}, errors.New("failed to find range statement in sub-test") } +func getTestDataAssignFromRange(rangeAst *ast.RangeStmt) *ast.AssignStmt { + spec := rangeAst.X.(*ast.Ident).Obj.Decl + if assignStmt, ok := spec.(*ast.AssignStmt); ok { + return assignStmt + } + if valueSpec, ok := spec.(*ast.ValueSpec); ok { + lhs := make([]ast.Expr, len(valueSpec.Names)) + for i, name := range valueSpec.Names { + lhs[i] = name + } + return &ast.AssignStmt{ + Lhs: lhs, + Tok: token.DEFINE, + Rhs: valueSpec.Values, + } + } + return nil +} // validate the test data assignment and return the associated metadata func processTestDataAssgn(sub string, assgn *ast.AssignStmt) (*subTData, bool) { @@ -309,3 +331,44 @@ func processRange(metadata *subTData, rastmt *ast.RangeStmt) bool { metadata.subTest = body return true } + +// resolveTestData resolves test data variable declared in cases_test.go (if exists) +func resolveTestData(fset *token.FileSet, f *ast.File, file string) { + filedata := filepath.Join(filepath.Dir(file), "cases_test.go") + fdata, _ := parser.ParseFile(fset, filedata, nil, parser.ParseComments) + + // NewPackage func always return errors because f files's missing import part + // so ignore checking the returned errors + if fdata != nil { + _, _ = ast.NewPackage(fset, map[string]*ast.File{file: f, filedata: fdata}, nil, nil) + } else { + _, _ = ast.NewPackage(fset, map[string]*ast.File{file: f}, nil, nil) + } +} + +// insertTestDataASTIntoFunc inserts testDataAst into the first line of fbAST function's body +func insertTestDataASTIntoFunc(fset *token.FileSet, testDataAst *ast.AssignStmt, fbAST *ast.BlockStmt, fileText []byte, pkgLine string) string { + buf := bytes.Buffer{} + + p := fset.Position(fbAST.Lbrace).Offset + 1 + + // write the beginning of fileText to func (...) { + buf.Write(fileText[:p+1]) + + // write test data assign stmt + if err := format.Node(&buf, fset, testDataAst); err != nil { + log.Println("warning: failed to format extracted AST for subtest") + return "" + } + // write the rest of fileText + buf.Write(fileText[p+1:]) + + // because assign stmt is extracted from different file, its indentation is different from fileText + // so need to reformat + src, err := format.Source((buf.Bytes())) + if err != nil { + log.Println("warning: failed to format extracted AST for subtest") + return "" + } + return strings.TrimSpace(strings.TrimPrefix(string(src), pkgLine)) +} diff --git a/testrunner/extract.go b/testrunner/extract.go index 3a8d371..b0120e8 100644 --- a/testrunner/extract.go +++ b/testrunner/extract.go @@ -53,7 +53,7 @@ func ExtractTestCodeAndTaskID(rootLevelTests map[string]rootLevelTest, testName return rootLevelTest.code, rootLevelTest.taskID } defer handleASTPanic() - subtc := getSubCode(test, subtest, rootLevelTest.code, rootLevelTest.fileName) + subtc := getSubCode(test, subtest, rootLevelTest.code, rootLevelTest.fileName, rootLevelTest.pkgName) if len(subtc) == 0 { return rootLevelTest.code, rootLevelTest.taskID } diff --git a/testrunner/extract_test.go b/testrunner/extract_test.go index b5be8bd..d877b19 100644 --- a/testrunner/extract_test.go +++ b/testrunner/extract_test.go @@ -211,6 +211,8 @@ func TestExtractTestCode(t *testing.T) { }`, }, } + tests = append(tests, testsDataSeparate...) + tests = append(tests, testsMultiAssignStmt...) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { code, _ := ExtractTestCodeAndTaskID(rootLevelTestsMap, tt.testName) @@ -241,3 +243,108 @@ func TestExtractTestCode(t *testing.T) { }) } } + +var testsDataSeparate = []struct { + name string + testName string + testFile string + code string +}{ + { + name: "working subtest with separate test data", + testName: "TestParseCard_Separate/parse_jack", + testFile: filepath.Join("testdata", "concept", "conditionals", "conditionals_test.go"), + code: `func TestParseCard_Separate(t *testing.T) { + tt := struct { + name string + card string + want int + }{ + name: "parse jack", + card: "jack", + want: 10, + } + + if got := ParseCard(tt.card); got != tt.want { + t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) + } + +}`, + }, { + name: "missing / not found subtest with separate test data", + testName: "TestParseCard_Separate/parse_missing_subtests", + testFile: filepath.Join("testdata", "concept", "conditionals", "conditionals_test.go"), + code: `func TestParseCard_Separate(t *testing.T) { + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + if got := ParseCard(tt.card); got != tt.want { + t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) + } + }) + } +}`, + }, { + name: "multiple statements with separate test data", + testName: "TestBlackjack_Separate/blackjack_with_ten_(ace_first)", + testFile: filepath.Join("testdata", "concept", "conditionals", "conditionals_test.go"), + code: `func TestBlackjack_Separate(t *testing.T) { + tt := struct { + name string + hand hand + want bool + }{ + name: "blackjack with ten (ace first)", + hand: hand{card1: "ace", card2: "ten"}, + want: true, + } + someAssignment := "test" + fmt.Println(someAssignment) + + _ = "literally anything" + + got := IsBlackjack(tt.hand.card1, tt.hand.card2) + if got != tt.want { + t.Errorf("IsBlackjack(%s, %s) = %t, want %t", tt.hand.card1, tt.hand.card2, got, tt.want) + } + + // Additional statements should be included + fmt.Println("the whole block") + fmt.Println("should be returned") +}`, + }, +} +var testsMultiAssignStmt = []struct { + name string + testName string + testFile string + code string +}{ + { + name: "subtest with arbitrary test data variable name, additional assign statements above and below test data", + testName: "TestSubtest_MultiAssignStmt/parse_king", + testFile: filepath.Join("testdata", "concept", "conditionals", "conditionals_test.go"), + code: `func TestSubtest_MultiAssignStmt(t *testing.T) { + someAssignment := "test" + + tt := struct { + name string + card string + want int + }{ + name: "parse king", + card: "king", + want: 10, + } + + someAssignment2 := "test2" + + if got := ParseCard(tt.card); got != tt.want { + t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) + } + + // Additional statements should be included + fmt.Println("the whole block") + fmt.Println("should be returned") +}`, + }, +} diff --git a/testrunner/testdata/concept/conditionals/cases_test.go b/testrunner/testdata/concept/conditionals/cases_test.go index 3f7e887..96c45f2 100644 --- a/testrunner/testdata/concept/conditionals/cases_test.go +++ b/testrunner/testdata/concept/conditionals/cases_test.go @@ -19,3 +19,62 @@ var allergicToTests = []struct { expected: false, }, } +var testcases = []struct { + name string + card string + want int +}{ + { + name: "parse two", + card: "two", + want: 2, + }, + { + name: "parse jack", + card: "jack", + want: 10, + }, + { + name: "parse king", + card: "king", + want: 10, + }, +} + +type hand struct { + card1, card2 string +} + +var testcases2 = []struct { + name string + hand hand + want bool +}{ + { + name: "blackjack with ten (ace first)", + hand: hand{card1: "ace", card2: "ten"}, + want: true, + }, + { + name: "blackjack with jack (ace first)", + hand: hand{card1: "ace", card2: "jack"}, + want: true, + }, + { + name: "blackjack with queen (ace first)", + hand: hand{ + card1: "ace", card2: "queen" + }, + want: true, + }, + { + name: "blackjack with king (ace first)", + hand: hand{card1: "ace", card2: "king"}, + want: true, + }, + { + name: "no blackjack with eight and five", + hand: hand{card2: "eight", card1: "five"}, + want: false, + }, +} diff --git a/testrunner/testdata/concept/conditionals/conditionals_test.go b/testrunner/testdata/concept/conditionals/conditionals_test.go index 6d11143..4bb3e87 100644 --- a/testrunner/testdata/concept/conditionals/conditionals_test.go +++ b/testrunner/testdata/concept/conditionals/conditionals_test.go @@ -143,3 +143,71 @@ func TestBlackjack(t *testing.T) { fmt.Println("the whole block") fmt.Println("should be returned") } +func TestParseCard_Separate(t *testing.T) { + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + if got := ParseCard(tt.card); got != tt.want { + t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) + } + }) + } +} + +func TestBlackjack_Separate(t *testing.T) { + someAssignment := "test" + fmt.Println(someAssignment) + + _ = "literally anything" + + for _, tt := range testcases2 { + t.Run(tt.name, func(t *testing.T) { + got := IsBlackjack(tt.hand.card1, tt.hand.card2) + if got != tt.want { + t.Errorf("IsBlackjack(%s, %s) = %t, want %t", tt.hand.card1, tt.hand.card2, got, tt.want) + } + }) + } + + // Additional statements should be included + fmt.Println("the whole block") + fmt.Println("should be returned") +} +func TestSubtest_MultiAssignStmt(t *testing.T) { + someAssignment := "test" + + myTests := []struct { + name string + card string + want int + }{ + { + name: "parse two", + card: "two", + want: 2, + }, + { + name: "parse jack", + card: "jack", + want: 10, + }, + { + name: "parse king", + card: "king", + want: 10, + }, + } + + someAssignment2 := "test2" + + for _, tt := range myTests { + t.Run(tt.name, func(t *testing.T) { + if got := ParseCard(tt.card); got != tt.want { + t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) + } + }) + } + + // Additional statements should be included + fmt.Println("the whole block") + fmt.Println("should be returned") +} From 21b939f42fa3c74c3f1188d97f4ab0dfed04a437 Mon Sep 17 00:00:00 2001 From: "meo.con.batu" Date: Thu, 28 Sep 2023 03:15:19 +0800 Subject: [PATCH 2/3] update smoke tests --- tests/all-fail/expected_results.json | 18 +++++++++--------- tests/partial-fail/expected_results.json | 18 +++++++++--------- tests/success/expected_results.json | 18 +++++++++--------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/all-fail/expected_results.json b/tests/all-fail/expected_results.json index e3d5122..77a3fe3 100644 --- a/tests/all-fail/expected_results.json +++ b/tests/all-fail/expected_results.json @@ -5,55 +5,55 @@ { "name": "TestLeapYears/ year not divisible by 4 in common year", "status": "fail", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year not divisible by 4 in common year\",\n\t\tyear: 2015,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_not_divisible_by_4_in_common_year\n\n leap_test.go:10: IsLeapYear(2015) = true, want false\n\n--- FAIL: TestLeapYears/year_not_divisible_by_4_in_common_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 2, not divisible by 4 in common year", "status": "fail", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 2, not divisible by 4 in common year\",\n\t\tyear: 1970,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_2,_not_divisible_by_4_in_common_year\n\n leap_test.go:10: IsLeapYear(1970) = true, want false\n\n--- FAIL: TestLeapYears/year_divisible_by_2,_not_divisible_by_4_in_common_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 4, not divisible by 100 in leap year", "status": "fail", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 4, not divisible by 100 in leap year\",\n\t\tyear: 1996,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_4,_not_divisible_by_100_in_leap_year\n\n leap_test.go:10: IsLeapYear(1996) = false, want true\n\n--- FAIL: TestLeapYears/year_divisible_by_4,_not_divisible_by_100_in_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 4 and 5 is still a leap year", "status": "fail", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 4 and 5 is still a leap year\",\n\t\tyear: 1960,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_4_and_5_is_still_a_leap_year\n\n leap_test.go:10: IsLeapYear(1960) = false, want true\n\n--- FAIL: TestLeapYears/year_divisible_by_4_and_5_is_still_a_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 100, not divisible by 400 in common year", "status": "fail", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 100, not divisible by 400 in common year\",\n\t\tyear: 2100,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_100,_not_divisible_by_400_in_common_year\n\n leap_test.go:10: IsLeapYear(2100) = true, want false\n\n--- FAIL: TestLeapYears/year_divisible_by_100,_not_divisible_by_400_in_common_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 100 but not by 3 is still not a leap year", "status": "fail", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 100 but not by 3 is still not a leap year\",\n\t\tyear: 1900,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_100_but_not_by_3_is_still_not_a_leap_year\n\n leap_test.go:10: IsLeapYear(1900) = true, want false\n\n--- FAIL: TestLeapYears/year_divisible_by_100_but_not_by_3_is_still_not_a_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 400 is leap year", "status": "fail", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 400 is leap year\",\n\t\tyear: 2000,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_400_is_leap_year\n\n leap_test.go:10: IsLeapYear(2000) = false, want true\n\n--- FAIL: TestLeapYears/year_divisible_by_400_is_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 400 but not by 125 is still a leap year", "status": "fail", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 400 but not by 125 is still a leap year\",\n\t\tyear: 2400,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_400_but_not_by_125_is_still_a_leap_year\n\n leap_test.go:10: IsLeapYear(2400) = false, want true\n\n--- FAIL: TestLeapYears/year_divisible_by_400_but_not_by_125_is_still_a_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 200, not divisible by 400 in common year", "status": "fail", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 200, not divisible by 400 in common year\",\n\t\tyear: 1800,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_200,_not_divisible_by_400_in_common_year\n\n leap_test.go:10: IsLeapYear(1800) = true, want false\n\n--- FAIL: TestLeapYears/year_divisible_by_200,_not_divisible_by_400_in_common_year (0.00s)\n" } ] diff --git a/tests/partial-fail/expected_results.json b/tests/partial-fail/expected_results.json index f3d6422..1b837f6 100644 --- a/tests/partial-fail/expected_results.json +++ b/tests/partial-fail/expected_results.json @@ -5,55 +5,55 @@ { "name": "TestLeapYears/ year not divisible by 4 in common year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year not divisible by 4 in common year\",\n\t\tyear: 2015,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_not_divisible_by_4_in_common_year\n\n--- PASS: TestLeapYears/year_not_divisible_by_4_in_common_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 2, not divisible by 4 in common year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 2, not divisible by 4 in common year\",\n\t\tyear: 1970,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_2,_not_divisible_by_4_in_common_year\n\n--- PASS: TestLeapYears/year_divisible_by_2,_not_divisible_by_4_in_common_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 4, not divisible by 100 in leap year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 4, not divisible by 100 in leap year\",\n\t\tyear: 1996,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_4,_not_divisible_by_100_in_leap_year\n\n--- PASS: TestLeapYears/year_divisible_by_4,_not_divisible_by_100_in_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 4 and 5 is still a leap year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 4 and 5 is still a leap year\",\n\t\tyear: 1960,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_4_and_5_is_still_a_leap_year\n\n--- PASS: TestLeapYears/year_divisible_by_4_and_5_is_still_a_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 100, not divisible by 400 in common year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 100, not divisible by 400 in common year\",\n\t\tyear: 2100,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_100,_not_divisible_by_400_in_common_year\n\n--- PASS: TestLeapYears/year_divisible_by_100,_not_divisible_by_400_in_common_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 100 but not by 3 is still not a leap year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 100 but not by 3 is still not a leap year\",\n\t\tyear: 1900,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_100_but_not_by_3_is_still_not_a_leap_year\n\n--- PASS: TestLeapYears/year_divisible_by_100_but_not_by_3_is_still_not_a_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 400 is leap year", "status": "fail", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 400 is leap year\",\n\t\tyear: 2000,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_400_is_leap_year\n\n leap_test.go:10: IsLeapYear(2000) = false, want true\n\n--- FAIL: TestLeapYears/year_divisible_by_400_is_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 400 but not by 125 is still a leap year", "status": "fail", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 400 but not by 125 is still a leap year\",\n\t\tyear: 2400,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_400_but_not_by_125_is_still_a_leap_year\n\n leap_test.go:10: IsLeapYear(2400) = false, want true\n\n--- FAIL: TestLeapYears/year_divisible_by_400_but_not_by_125_is_still_a_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 200, not divisible by 400 in common year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 200, not divisible by 400 in common year\",\n\t\tyear: 1800,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_200,_not_divisible_by_400_in_common_year\n\n--- PASS: TestLeapYears/year_divisible_by_200,_not_divisible_by_400_in_common_year (0.00s)\n" } ] diff --git a/tests/success/expected_results.json b/tests/success/expected_results.json index e33b7b7..10c1acc 100644 --- a/tests/success/expected_results.json +++ b/tests/success/expected_results.json @@ -5,55 +5,55 @@ { "name": "TestLeapYears/ year not divisible by 4 in common year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year not divisible by 4 in common year\",\n\t\tyear: 2015,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_not_divisible_by_4_in_common_year\n\n--- PASS: TestLeapYears/year_not_divisible_by_4_in_common_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 2, not divisible by 4 in common year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 2, not divisible by 4 in common year\",\n\t\tyear: 1970,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_2,_not_divisible_by_4_in_common_year\n\n--- PASS: TestLeapYears/year_divisible_by_2,_not_divisible_by_4_in_common_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 4, not divisible by 100 in leap year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 4, not divisible by 100 in leap year\",\n\t\tyear: 1996,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_4,_not_divisible_by_100_in_leap_year\n\n--- PASS: TestLeapYears/year_divisible_by_4,_not_divisible_by_100_in_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 4 and 5 is still a leap year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 4 and 5 is still a leap year\",\n\t\tyear: 1960,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_4_and_5_is_still_a_leap_year\n\n--- PASS: TestLeapYears/year_divisible_by_4_and_5_is_still_a_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 100, not divisible by 400 in common year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 100, not divisible by 400 in common year\",\n\t\tyear: 2100,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_100,_not_divisible_by_400_in_common_year\n\n--- PASS: TestLeapYears/year_divisible_by_100,_not_divisible_by_400_in_common_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 100 but not by 3 is still not a leap year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 100 but not by 3 is still not a leap year\",\n\t\tyear: 1900,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_100_but_not_by_3_is_still_not_a_leap_year\n\n--- PASS: TestLeapYears/year_divisible_by_100_but_not_by_3_is_still_not_a_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 400 is leap year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 400 is leap year\",\n\t\tyear: 2000,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_400_is_leap_year\n\n--- PASS: TestLeapYears/year_divisible_by_400_is_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 400 but not by 125 is still a leap year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 400 but not by 125 is still a leap year\",\n\t\tyear: 2400,\n\t\texpected: true,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_400_but_not_by_125_is_still_a_leap_year\n\n--- PASS: TestLeapYears/year_divisible_by_400_but_not_by_125_is_still_a_leap_year (0.00s)\n" }, { "name": "TestLeapYears/ year divisible by 200, not divisible by 400 in common year", "status": "pass", - "test_code": "func TestLeapYears(t *testing.T) {\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.description, func(t *testing.T) {\n\t\t\tactual := IsLeapYear(tc.year)\n\t\t\tif actual != tc.expected {\n\t\t\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t\t\t}\n\t\t})\n\t}\n}", + "test_code": "func TestLeapYears(t *testing.T) {\n\ttc := struct {\n\t\tdescription string\n\t\tyear int\n\t\texpected bool\n\t}{\n\t\tdescription: \"year divisible by 200, not divisible by 400 in common year\",\n\t\tyear: 1800,\n\t\texpected: false,\n\t}\n\n\tactual := IsLeapYear(tc.year)\n\tif actual != tc.expected {\n\t\tt.Fatalf(\"IsLeapYear(%d) = %t, want %t\", tc.year, actual, tc.expected)\n\t}\n\n}", "message": "\n=== RUN TestLeapYears/year_divisible_by_200,_not_divisible_by_400_in_common_year\n\n--- PASS: TestLeapYears/year_divisible_by_200,_not_divisible_by_400_in_common_year (0.00s)\n" } ] From 96e2c00db8d66e0868590883ed0698c6efe01f53 Mon Sep 17 00:00:00 2001 From: "meo.con.batu" Date: Mon, 16 Oct 2023 05:06:13 +0800 Subject: [PATCH 3/3] create separate_cases_file test data --- integration_test.go | 4 + testrunner/extract_test.go | 107 ------------------ .../concept/conditionals/cases_test.go | 59 ---------- .../concept/conditionals/conditionals_test.go | 68 ----------- .../expected/separate_cases_file.json | 72 ++++++++++++ .../separate_cases_file/.meta/config.json | 23 ++++ .../separate_cases_file/cases_test.go | 61 ++++++++++ .../separate_cases_file/conditionals.go | 59 ++++++++++ .../separate_cases_file/conditionals_test.go | 77 +++++++++++++ .../practice/separate_cases_file/go.mod | 3 + 10 files changed, 299 insertions(+), 234 deletions(-) create mode 100644 testrunner/testdata/expected/separate_cases_file.json create mode 100644 testrunner/testdata/practice/separate_cases_file/.meta/config.json create mode 100644 testrunner/testdata/practice/separate_cases_file/cases_test.go create mode 100644 testrunner/testdata/practice/separate_cases_file/conditionals.go create mode 100644 testrunner/testdata/practice/separate_cases_file/conditionals_test.go create mode 100644 testrunner/testdata/practice/separate_cases_file/go.mod diff --git a/integration_test.go b/integration_test.go index 1e325fe..2e5ba56 100644 --- a/integration_test.go +++ b/integration_test.go @@ -75,6 +75,10 @@ func TestIntegration(t *testing.T) { inputDir: filepath.Join("testrunner", "testdata", "practice", "pkg_level_error"), expected: filepath.Join("testrunner", "testdata", "expected", "pkg_level_error.json"), }, + { + inputDir: filepath.Join("testrunner", "testdata", "practice", "separate_cases_file"), + expected: filepath.Join("testrunner", "testdata", "expected", "separate_cases_file.json"), + }, { inputDir: filepath.Join("testrunner", "testdata", "practice", "failing"), expected: filepath.Join("testrunner", "testdata", "expected", "failing.json"), diff --git a/testrunner/extract_test.go b/testrunner/extract_test.go index d877b19..b5be8bd 100644 --- a/testrunner/extract_test.go +++ b/testrunner/extract_test.go @@ -211,8 +211,6 @@ func TestExtractTestCode(t *testing.T) { }`, }, } - tests = append(tests, testsDataSeparate...) - tests = append(tests, testsMultiAssignStmt...) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { code, _ := ExtractTestCodeAndTaskID(rootLevelTestsMap, tt.testName) @@ -243,108 +241,3 @@ func TestExtractTestCode(t *testing.T) { }) } } - -var testsDataSeparate = []struct { - name string - testName string - testFile string - code string -}{ - { - name: "working subtest with separate test data", - testName: "TestParseCard_Separate/parse_jack", - testFile: filepath.Join("testdata", "concept", "conditionals", "conditionals_test.go"), - code: `func TestParseCard_Separate(t *testing.T) { - tt := struct { - name string - card string - want int - }{ - name: "parse jack", - card: "jack", - want: 10, - } - - if got := ParseCard(tt.card); got != tt.want { - t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) - } - -}`, - }, { - name: "missing / not found subtest with separate test data", - testName: "TestParseCard_Separate/parse_missing_subtests", - testFile: filepath.Join("testdata", "concept", "conditionals", "conditionals_test.go"), - code: `func TestParseCard_Separate(t *testing.T) { - for _, tt := range testcases { - t.Run(tt.name, func(t *testing.T) { - if got := ParseCard(tt.card); got != tt.want { - t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) - } - }) - } -}`, - }, { - name: "multiple statements with separate test data", - testName: "TestBlackjack_Separate/blackjack_with_ten_(ace_first)", - testFile: filepath.Join("testdata", "concept", "conditionals", "conditionals_test.go"), - code: `func TestBlackjack_Separate(t *testing.T) { - tt := struct { - name string - hand hand - want bool - }{ - name: "blackjack with ten (ace first)", - hand: hand{card1: "ace", card2: "ten"}, - want: true, - } - someAssignment := "test" - fmt.Println(someAssignment) - - _ = "literally anything" - - got := IsBlackjack(tt.hand.card1, tt.hand.card2) - if got != tt.want { - t.Errorf("IsBlackjack(%s, %s) = %t, want %t", tt.hand.card1, tt.hand.card2, got, tt.want) - } - - // Additional statements should be included - fmt.Println("the whole block") - fmt.Println("should be returned") -}`, - }, -} -var testsMultiAssignStmt = []struct { - name string - testName string - testFile string - code string -}{ - { - name: "subtest with arbitrary test data variable name, additional assign statements above and below test data", - testName: "TestSubtest_MultiAssignStmt/parse_king", - testFile: filepath.Join("testdata", "concept", "conditionals", "conditionals_test.go"), - code: `func TestSubtest_MultiAssignStmt(t *testing.T) { - someAssignment := "test" - - tt := struct { - name string - card string - want int - }{ - name: "parse king", - card: "king", - want: 10, - } - - someAssignment2 := "test2" - - if got := ParseCard(tt.card); got != tt.want { - t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) - } - - // Additional statements should be included - fmt.Println("the whole block") - fmt.Println("should be returned") -}`, - }, -} diff --git a/testrunner/testdata/concept/conditionals/cases_test.go b/testrunner/testdata/concept/conditionals/cases_test.go index 96c45f2..3f7e887 100644 --- a/testrunner/testdata/concept/conditionals/cases_test.go +++ b/testrunner/testdata/concept/conditionals/cases_test.go @@ -19,62 +19,3 @@ var allergicToTests = []struct { expected: false, }, } -var testcases = []struct { - name string - card string - want int -}{ - { - name: "parse two", - card: "two", - want: 2, - }, - { - name: "parse jack", - card: "jack", - want: 10, - }, - { - name: "parse king", - card: "king", - want: 10, - }, -} - -type hand struct { - card1, card2 string -} - -var testcases2 = []struct { - name string - hand hand - want bool -}{ - { - name: "blackjack with ten (ace first)", - hand: hand{card1: "ace", card2: "ten"}, - want: true, - }, - { - name: "blackjack with jack (ace first)", - hand: hand{card1: "ace", card2: "jack"}, - want: true, - }, - { - name: "blackjack with queen (ace first)", - hand: hand{ - card1: "ace", card2: "queen" - }, - want: true, - }, - { - name: "blackjack with king (ace first)", - hand: hand{card1: "ace", card2: "king"}, - want: true, - }, - { - name: "no blackjack with eight and five", - hand: hand{card2: "eight", card1: "five"}, - want: false, - }, -} diff --git a/testrunner/testdata/concept/conditionals/conditionals_test.go b/testrunner/testdata/concept/conditionals/conditionals_test.go index 4bb3e87..6d11143 100644 --- a/testrunner/testdata/concept/conditionals/conditionals_test.go +++ b/testrunner/testdata/concept/conditionals/conditionals_test.go @@ -143,71 +143,3 @@ func TestBlackjack(t *testing.T) { fmt.Println("the whole block") fmt.Println("should be returned") } -func TestParseCard_Separate(t *testing.T) { - for _, tt := range testcases { - t.Run(tt.name, func(t *testing.T) { - if got := ParseCard(tt.card); got != tt.want { - t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) - } - }) - } -} - -func TestBlackjack_Separate(t *testing.T) { - someAssignment := "test" - fmt.Println(someAssignment) - - _ = "literally anything" - - for _, tt := range testcases2 { - t.Run(tt.name, func(t *testing.T) { - got := IsBlackjack(tt.hand.card1, tt.hand.card2) - if got != tt.want { - t.Errorf("IsBlackjack(%s, %s) = %t, want %t", tt.hand.card1, tt.hand.card2, got, tt.want) - } - }) - } - - // Additional statements should be included - fmt.Println("the whole block") - fmt.Println("should be returned") -} -func TestSubtest_MultiAssignStmt(t *testing.T) { - someAssignment := "test" - - myTests := []struct { - name string - card string - want int - }{ - { - name: "parse two", - card: "two", - want: 2, - }, - { - name: "parse jack", - card: "jack", - want: 10, - }, - { - name: "parse king", - card: "king", - want: 10, - }, - } - - someAssignment2 := "test2" - - for _, tt := range myTests { - t.Run(tt.name, func(t *testing.T) { - if got := ParseCard(tt.card); got != tt.want { - t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) - } - }) - } - - // Additional statements should be included - fmt.Println("the whole block") - fmt.Println("should be returned") -} diff --git a/testrunner/testdata/expected/separate_cases_file.json b/testrunner/testdata/expected/separate_cases_file.json new file mode 100644 index 0000000..7168b46 --- /dev/null +++ b/testrunner/testdata/expected/separate_cases_file.json @@ -0,0 +1,72 @@ +{ + "status": "pass", + "version": 3, + "tests": [ + { + "name": "TestParseCard Separate/ parse two", + "status": "pass", + "test_code": "func TestParseCard_Separate(t *testing.T) {\n\ttt := struct {\n\t\tname string\n\t\tcard string\n\t\twant int\n\t}{\n\t\tname: \"parse two\",\n\t\tcard: \"two\",\n\t\twant: 2,\n\t}\n\n\tif got := ParseCard(tt.card); got != tt.want {\n\t\tt.Errorf(\"ParseCard(%s) = %d, want %d\", tt.card, got, tt.want)\n\t}\n\n}", + "message": "\n=== RUN TestParseCard_Separate/parse_two\n\n--- PASS: TestParseCard_Separate/parse_two \n" + }, + { + "name": "TestParseCard Separate/ parse jack", + "status": "pass", + "test_code": "func TestParseCard_Separate(t *testing.T) {\n\ttt := struct {\n\t\tname string\n\t\tcard string\n\t\twant int\n\t}{\n\t\tname: \"parse jack\",\n\t\tcard: \"jack\",\n\t\twant: 10,\n\t}\n\n\tif got := ParseCard(tt.card); got != tt.want {\n\t\tt.Errorf(\"ParseCard(%s) = %d, want %d\", tt.card, got, tt.want)\n\t}\n\n}", + "message": "\n=== RUN TestParseCard_Separate/parse_jack\n\n--- PASS: TestParseCard_Separate/parse_jack \n" + }, + { + "name": "TestParseCard Separate/ parse king", + "status": "pass", + "test_code": "func TestParseCard_Separate(t *testing.T) {\n\ttt := struct {\n\t\tname string\n\t\tcard string\n\t\twant int\n\t}{\n\t\tname: \"parse king\",\n\t\tcard: \"king\",\n\t\twant: 10,\n\t}\n\n\tif got := ParseCard(tt.card); got != tt.want {\n\t\tt.Errorf(\"ParseCard(%s) = %d, want %d\", tt.card, got, tt.want)\n\t}\n\n}", + "message": "\n=== RUN TestParseCard_Separate/parse_king\n\n--- PASS: TestParseCard_Separate/parse_king \n" + }, + { + "name": "TestBlackjack Separate/ blackjack with ten (ace first)", + "status": "pass", + "test_code": "func TestBlackjack_Separate(t *testing.T) {\n\ttt := struct {\n\t\tname string\n\t\thand hand\n\t\twant bool\n\t}{\n\t\tname: \"blackjack with ten (ace first)\",\n\t\thand: hand{card1: \"ace\", card2: \"ten\"},\n\t\twant: true,\n\t}\n\tsomeAssignment := \"test\"\n\tfmt.Println(someAssignment)\n\n\t_ = \"literally anything\"\n\n\tgot := IsBlackjack(tt.hand.card1, tt.hand.card2)\n\tif got != tt.want {\n\t\tt.Errorf(\"IsBlackjack(%s, %s) = %t, want %t\", tt.hand.card1, tt.hand.card2, got, tt.want)\n\t}\n\n\t// Additional statements should be included\n\tfmt.Println(\"the whole block\")\n\tfmt.Println(\"should be returned\")\n}", + "message": "\n=== RUN TestBlackjack_Separate/blackjack_with_ten_(ace_first)\n\n--- PASS: TestBlackjack_Separate/blackjack_with_ten_(ace_first) \n" + }, + { + "name": "TestBlackjack Separate/ blackjack with jack (ace first)", + "status": "pass", + "test_code": "func TestBlackjack_Separate(t *testing.T) {\n\ttt := struct {\n\t\tname string\n\t\thand hand\n\t\twant bool\n\t}{\n\t\tname: \"blackjack with jack (ace first)\",\n\t\thand: hand{card1: \"ace\", card2: \"jack\"},\n\t\twant: true,\n\t}\n\tsomeAssignment := \"test\"\n\tfmt.Println(someAssignment)\n\n\t_ = \"literally anything\"\n\n\tgot := IsBlackjack(tt.hand.card1, tt.hand.card2)\n\tif got != tt.want {\n\t\tt.Errorf(\"IsBlackjack(%s, %s) = %t, want %t\", tt.hand.card1, tt.hand.card2, got, tt.want)\n\t}\n\n\t// Additional statements should be included\n\tfmt.Println(\"the whole block\")\n\tfmt.Println(\"should be returned\")\n}", + "message": "\n=== RUN TestBlackjack_Separate/blackjack_with_jack_(ace_first)\n\n--- PASS: TestBlackjack_Separate/blackjack_with_jack_(ace_first) \n" + }, + { + "name": "TestBlackjack Separate/ blackjack with queen (ace first)", + "status": "pass", + "test_code": "func TestBlackjack_Separate(t *testing.T) {\n\ttt := struct {\n\t\tname string\n\t\thand hand\n\t\twant bool\n\t}{\n\t\tname: \"blackjack with queen (ace first)\",\n\t\thand: hand{\n\t\t\tcard1: \"ace\", card2: \"queen\",\n\t\t},\n\t\twant: true,\n\t}\n\tsomeAssignment := \"test\"\n\tfmt.Println(someAssignment)\n\n\t_ = \"literally anything\"\n\n\tgot := IsBlackjack(tt.hand.card1, tt.hand.card2)\n\tif got != tt.want {\n\t\tt.Errorf(\"IsBlackjack(%s, %s) = %t, want %t\", tt.hand.card1, tt.hand.card2, got, tt.want)\n\t}\n\n\t// Additional statements should be included\n\tfmt.Println(\"the whole block\")\n\tfmt.Println(\"should be returned\")\n}", + "message": "\n=== RUN TestBlackjack_Separate/blackjack_with_queen_(ace_first)\n\n--- PASS: TestBlackjack_Separate/blackjack_with_queen_(ace_first) \n" + }, + { + "name": "TestBlackjack Separate/ blackjack with king (ace first)", + "status": "pass", + "test_code": "func TestBlackjack_Separate(t *testing.T) {\n\ttt := struct {\n\t\tname string\n\t\thand hand\n\t\twant bool\n\t}{\n\t\tname: \"blackjack with king (ace first)\",\n\t\thand: hand{card1: \"ace\", card2: \"king\"},\n\t\twant: true,\n\t}\n\tsomeAssignment := \"test\"\n\tfmt.Println(someAssignment)\n\n\t_ = \"literally anything\"\n\n\tgot := IsBlackjack(tt.hand.card1, tt.hand.card2)\n\tif got != tt.want {\n\t\tt.Errorf(\"IsBlackjack(%s, %s) = %t, want %t\", tt.hand.card1, tt.hand.card2, got, tt.want)\n\t}\n\n\t// Additional statements should be included\n\tfmt.Println(\"the whole block\")\n\tfmt.Println(\"should be returned\")\n}", + "message": "\n=== RUN TestBlackjack_Separate/blackjack_with_king_(ace_first)\n\n--- PASS: TestBlackjack_Separate/blackjack_with_king_(ace_first) \n" + }, + { + "name": "TestBlackjack Separate/ no blackjack with eight and five", + "status": "pass", + "test_code": "func TestBlackjack_Separate(t *testing.T) {\n\ttt := struct {\n\t\tname string\n\t\thand hand\n\t\twant bool\n\t}{\n\t\tname: \"no blackjack with eight and five\",\n\t\thand: hand{card2: \"eight\", card1: \"five\"},\n\t\twant: false,\n\t}\n\tsomeAssignment := \"test\"\n\tfmt.Println(someAssignment)\n\n\t_ = \"literally anything\"\n\n\tgot := IsBlackjack(tt.hand.card1, tt.hand.card2)\n\tif got != tt.want {\n\t\tt.Errorf(\"IsBlackjack(%s, %s) = %t, want %t\", tt.hand.card1, tt.hand.card2, got, tt.want)\n\t}\n\n\t// Additional statements should be included\n\tfmt.Println(\"the whole block\")\n\tfmt.Println(\"should be returned\")\n}", + "message": "\n=== RUN TestBlackjack_Separate/no_blackjack_with_eight_and_five\n\n--- PASS: TestBlackjack_Separate/no_blackjack_with_eight_and_five \n" + }, + { + "name": "TestSubtest MultiAssignStmt/ parse two", + "status": "pass", + "test_code": "func TestSubtest_MultiAssignStmt(t *testing.T) {\n\tsomeAssignment := \"test\"\n\tfmt.Println(someAssignment)\n\n\ttt := struct {\n\t\tname string\n\t\tcard string\n\t\twant int\n\t}{\n\t\tname: \"parse two\",\n\t\tcard: \"two\",\n\t\twant: 2,\n\t}\n\n\tsomeAssignment2 := \"test2\"\n\tfmt.Println(someAssignment2)\n\n\tif got := ParseCard(tt.card); got != tt.want {\n\t\tt.Errorf(\"ParseCard(%s) = %d, want %d\", tt.card, got, tt.want)\n\t}\n\n\t// Additional statements should be included\n\tfmt.Println(\"the whole block\")\n\tfmt.Println(\"should be returned\")\n}", + "message": "\n=== RUN TestSubtest_MultiAssignStmt/parse_two\n\n--- PASS: TestSubtest_MultiAssignStmt/parse_two \n" + }, + { + "name": "TestSubtest MultiAssignStmt/ parse jack", + "status": "pass", + "test_code": "func TestSubtest_MultiAssignStmt(t *testing.T) {\n\tsomeAssignment := \"test\"\n\tfmt.Println(someAssignment)\n\n\ttt := struct {\n\t\tname string\n\t\tcard string\n\t\twant int\n\t}{\n\t\tname: \"parse jack\",\n\t\tcard: \"jack\",\n\t\twant: 10,\n\t}\n\n\tsomeAssignment2 := \"test2\"\n\tfmt.Println(someAssignment2)\n\n\tif got := ParseCard(tt.card); got != tt.want {\n\t\tt.Errorf(\"ParseCard(%s) = %d, want %d\", tt.card, got, tt.want)\n\t}\n\n\t// Additional statements should be included\n\tfmt.Println(\"the whole block\")\n\tfmt.Println(\"should be returned\")\n}", + "message": "\n=== RUN TestSubtest_MultiAssignStmt/parse_jack\n\n--- PASS: TestSubtest_MultiAssignStmt/parse_jack \n" + }, + { + "name": "TestSubtest MultiAssignStmt/ parse king", + "status": "pass", + "test_code": "func TestSubtest_MultiAssignStmt(t *testing.T) {\n\tsomeAssignment := \"test\"\n\tfmt.Println(someAssignment)\n\n\ttt := struct {\n\t\tname string\n\t\tcard string\n\t\twant int\n\t}{\n\t\tname: \"parse king\",\n\t\tcard: \"king\",\n\t\twant: 10,\n\t}\n\n\tsomeAssignment2 := \"test2\"\n\tfmt.Println(someAssignment2)\n\n\tif got := ParseCard(tt.card); got != tt.want {\n\t\tt.Errorf(\"ParseCard(%s) = %d, want %d\", tt.card, got, tt.want)\n\t}\n\n\t// Additional statements should be included\n\tfmt.Println(\"the whole block\")\n\tfmt.Println(\"should be returned\")\n}", + "message": "\n=== RUN TestSubtest_MultiAssignStmt/parse_king\n\n--- PASS: TestSubtest_MultiAssignStmt/parse_king \n" + } + ] +} \ No newline at end of file diff --git a/testrunner/testdata/practice/separate_cases_file/.meta/config.json b/testrunner/testdata/practice/separate_cases_file/.meta/config.json new file mode 100644 index 0000000..39dcd6d --- /dev/null +++ b/testrunner/testdata/practice/separate_cases_file/.meta/config.json @@ -0,0 +1,23 @@ +{ + "blurb": "...", + "authors": [ + "..." + ], + "contributors": [ + "..." + ], + "files": { + "solution": [ + "conditionals.go" + ], + "test": [ + "conditionals_test.go" + ], + "example": [ + ".meta/example.go" + ] + }, + "custom": { + "taskIdsEnabled": false + } +} diff --git a/testrunner/testdata/practice/separate_cases_file/cases_test.go b/testrunner/testdata/practice/separate_cases_file/cases_test.go new file mode 100644 index 0000000..cd63f29 --- /dev/null +++ b/testrunner/testdata/practice/separate_cases_file/cases_test.go @@ -0,0 +1,61 @@ +package conditionals + +var testcases = []struct { + name string + card string + want int +}{ + { + name: "parse two", + card: "two", + want: 2, + }, + { + name: "parse jack", + card: "jack", + want: 10, + }, + { + name: "parse king", + card: "king", + want: 10, + }, +} + +type hand struct { + card1, card2 string +} + +var testcases2 = []struct { + name string + hand hand + want bool +}{ + { + name: "blackjack with ten (ace first)", + hand: hand{card1: "ace", card2: "ten"}, + want: true, + }, + { + name: "blackjack with jack (ace first)", + hand: hand{card1: "ace", card2: "jack"}, + want: true, + }, + { + name: "blackjack with queen (ace first)", + hand: hand{ + card1: "ace", card2: "queen", + }, + want: true, + }, + { + name: "blackjack with king (ace first)", + hand: hand{card1: "ace", card2: "king"}, + want: true, + }, + { + name: "no blackjack with eight and five", + hand: hand{card2: "eight", card1: "five"}, + want: false, + }, +} diff --git a/testrunner/testdata/practice/separate_cases_file/conditionals.go b/testrunner/testdata/practice/separate_cases_file/conditionals.go new file mode 100644 index 0000000..2cc28c9 --- /dev/null +++ b/testrunner/testdata/practice/separate_cases_file/conditionals.go @@ -0,0 +1,59 @@ +package conditionals + +// ParseCard returns the integer value of a card following blackjack ruleset. +func ParseCard(card string) int { + val := 0 + switch card { + case "ace": + val = 11 + case "ten", "jack", "queen", "king": + val = 10 + case "one": + val = 1 + case "two": + val = 2 + case "three": + val = 3 + case "four": + val = 4 + case "five": + val = 5 + case "six": + val = 6 + case "seven": + val = 7 + case "eight": + val = 8 + case "nine": + val = 9 + } + return val +} + +// IsBlackjack returns true if the player has a blackjack, false otherwise. +func IsBlackjack(card1, card2 string) bool { + return ParseCard(card1)+ParseCard(card2) == 21 +} + +// LargeHand implements the decision tree for hand scores larger than 20 points. +func LargeHand(isBlackjack bool, dealerScore int) string { + panic("Please implement the LargeHand function") +} + +// SmallHand implements the decision tree for hand scores with less than 21 points. +func SmallHand(handScore int, dealerScore int) string { + panic("Please implement the SmallHand function") +} + +// FirstTurn returns the semi-optimal decision for the first turn, given the cards of the player and the dealer. +// This function is already implemented and does not need to be edited. It pulls the other functions together in a +// complete decision tree for the first turn. +func FirstTurn(card1, card2, dealerCard string) string { + handScore := ParseCard(card1) + ParseCard(card2) + dealerScore := ParseCard(dealerCard) + + if 20 < handScore { + return LargeHand(IsBlackjack(card1, card2), dealerScore) + } + return SmallHand(handScore, dealerScore) +} diff --git a/testrunner/testdata/practice/separate_cases_file/conditionals_test.go b/testrunner/testdata/practice/separate_cases_file/conditionals_test.go new file mode 100644 index 0000000..4fb2474 --- /dev/null +++ b/testrunner/testdata/practice/separate_cases_file/conditionals_test.go @@ -0,0 +1,77 @@ +package conditionals + +import ( + "fmt" + "testing" +) + +func TestParseCard_Separate(t *testing.T) { + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + if got := ParseCard(tt.card); got != tt.want { + t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) + } + }) + } +} + +func TestBlackjack_Separate(t *testing.T) { + someAssignment := "test" + fmt.Println(someAssignment) + + _ = "literally anything" + + for _, tt := range testcases2 { + t.Run(tt.name, func(t *testing.T) { + got := IsBlackjack(tt.hand.card1, tt.hand.card2) + if got != tt.want { + t.Errorf("IsBlackjack(%s, %s) = %t, want %t", tt.hand.card1, tt.hand.card2, got, tt.want) + } + }) + } + + // Additional statements should be included + fmt.Println("the whole block") + fmt.Println("should be returned") +} +func TestSubtest_MultiAssignStmt(t *testing.T) { + someAssignment := "test" + fmt.Println(someAssignment) + + myTests := []struct { + name string + card string + want int + }{ + { + name: "parse two", + card: "two", + want: 2, + }, + { + name: "parse jack", + card: "jack", + want: 10, + }, + { + name: "parse king", + card: "king", + want: 10, + }, + } + + someAssignment2 := "test2" + fmt.Println(someAssignment2) + + for _, tt := range myTests { + t.Run(tt.name, func(t *testing.T) { + if got := ParseCard(tt.card); got != tt.want { + t.Errorf("ParseCard(%s) = %d, want %d", tt.card, got, tt.want) + } + }) + } + + // Additional statements should be included + fmt.Println("the whole block") + fmt.Println("should be returned") +} diff --git a/testrunner/testdata/practice/separate_cases_file/go.mod b/testrunner/testdata/practice/separate_cases_file/go.mod new file mode 100644 index 0000000..ceac322 --- /dev/null +++ b/testrunner/testdata/practice/separate_cases_file/go.mod @@ -0,0 +1,3 @@ +module conditionals + +go 1.18