Add io.Reader variant

Move core logic to ParseTestCases,
which operates on an io.Reader,
but keep the file-based function around for convenience.
This commit is contained in:
Abhinav Gupta 2022-11-10 23:45:31 -08:00
parent 86794e96ee
commit 8fe644f01f
2 changed files with 32 additions and 26 deletions

View file

@ -6,6 +6,7 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"io"
"os"
"regexp"
"runtime/debug"
@ -99,10 +100,7 @@ func (e *testCaseParseError) Unwrap() error {
return e.Err
}
// ParseTestCaseFile parses the contents of the given test case file
// and reurns the test cases found inside.
//
// The file should contain zero or more test cases, each in the form:
// ParseTestCases parses test cases from a source in the following format:
//
// NUM[:DESC]
// [OPTIONS]
@ -143,13 +141,7 @@ func (e *testCaseParseError) Unwrap() error {
// //- - - - - - - - -//
// Hello, **world**.
// [..]
func ParseTestCaseFile(filename string) ([]MarkdownTestCase, error) {
fp, err := os.Open(filename)
if err != nil {
return nil, err
}
defer fp.Close()
func ParseTestCases(fp io.Reader) ([]MarkdownTestCase, error) {
scanner := bufio.NewScanner(fp)
c := MarkdownTestCase{
No: -1,
@ -169,6 +161,7 @@ func ParseTestCaseFile(filename string) ([]MarkdownTestCase, error) {
}
}
var err error
for scanner.Scan() {
line++
if util.IsBlank([]byte(scanner.Text())) {
@ -232,6 +225,18 @@ func ParseTestCaseFile(filename string) ([]MarkdownTestCase, error) {
return cases, nil
}
// ParseTestCaseFile reads test cases as described by [ParseTestCases]
// from an external file.
func ParseTestCaseFile(filename string) ([]MarkdownTestCase, error) {
fp, err := os.Open(filename)
if err != nil {
return nil, err
}
defer fp.Close()
return ParseTestCases(fp)
}
// DoTestCaseFile runs test cases in a given file.
func DoTestCaseFile(m goldmark.Markdown, filename string, t TestingT, no ...int) {
allCases, err := ParseTestCaseFile(filename)

View file

@ -3,7 +3,6 @@ package testutil
import (
"errors"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
@ -13,7 +12,7 @@ import (
// that doesn't conform to testing.T.
var _ TestingT = (*testing.T)(nil)
func TestParseTestCaseFile(t *testing.T) {
func TestParseTestCases(t *testing.T) {
tests := []struct {
desc string
give string // contents of the test file
@ -85,12 +84,7 @@ func TestParseTestCaseFile(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
filename := filepath.Join(t.TempDir(), "give.txt")
if err := os.WriteFile(filename, []byte(tt.give), 0o644); err != nil {
t.Fatal(err)
}
got, err := ParseTestCaseFile(filename)
got, err := ParseTestCases(strings.NewReader(tt.give))
if err != nil {
t.Fatalf("could not parse: %v", err)
}
@ -104,7 +98,7 @@ func TestParseTestCaseFile(t *testing.T) {
}
}
func TestParseTestCaseFile_Errors(t *testing.T) {
func TestParseTestCases_Errors(t *testing.T) {
tests := []struct {
desc string
give string // contents of the test file
@ -166,12 +160,7 @@ func TestParseTestCaseFile_Errors(t *testing.T) {
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
filename := filepath.Join(t.TempDir(), "give.txt")
if err := os.WriteFile(filename, []byte(tt.give), 0o644); err != nil {
t.Fatal(err)
}
cases, err := ParseTestCaseFile(filename)
cases, err := ParseTestCases(strings.NewReader(tt.give))
if err == nil {
t.Fatalf("expected error, got:\n%#v", cases)
}
@ -185,6 +174,18 @@ func TestParseTestCaseFile_Errors(t *testing.T) {
}
}
func TestParseTestCaseFile_Error(t *testing.T) {
cases, err := ParseTestCaseFile("does_not_exist.txt")
if err == nil {
t.Fatalf("expected error, got:\n%#v", cases)
}
if !errors.Is(err, os.ErrNotExist) {
t.Errorf(" unexpected error = %v", err)
t.Errorf("expected unwrap to = %v", os.ErrNotExist)
}
}
func TestTestCaseParseError(t *testing.T) {
wrapped := errors.New("great sadness")
err := &testCaseParseError{Line: 42, Err: wrapped}