testmark-go

suite: Revisit names to reduce stutter.

commit 921077c4fe87e409558e65935c6a6de7170cea2e · parent 04a9a8ce6c · browse this tree
Eric Myhre, 2023-05-10 12:41:22 UTC

Also change the name of "TestingPattern" to "TestingFunctor", because
I noticed I used the word "pattern" to describe both globs as well
as the callback interface, and that's quite confusing.
diff --git a/suite/suite.go b/suite/suite.go
index 392fdd8..757b95d 100644
--- a/suite/suite.go
+++ b/suite/suite.go
@@ -11,41 +11,41 @@ import (
 	"github.com/warpfork/go-testmark"
 )
 
-// NewSuiteManager constructs a suite manager with which you can use WorkWith to register
-// patterns of filenames and hunknames within them with a TestingPattern,
+// NewManager constructs a suite manager with which you can use WorkWith to register
+// patterns of filenames and hunknames within them with a TestingFunctor,
 // and then run the whole suite together.
 //
 // Note that if you want automatic fixture regen features to work,
 // the filesystem you hand in to this constructor must support `fsx.FSSupportingWrite`.
 // (In practice, this often means you want to use `github.com/warpfork/go-fsx/osfs.DirFS`
 // where you otherwise might've used stdlib `os.DirFS` to construct the filesystem reference.)
-func NewSuiteManager(fs fsx.FS) *SuiteManager {
-	return &SuiteManager{
+func NewManager(fs fsx.FS) *Manager {
+	return &Manager{
 		fs:      fs,
 		workset: make(map[string]fileContentExpectations),
 	}
 }
 
-// Using SuiteManager to run tests is not strictly necessary,
+// Using suite.Manager to run tests is not strictly necessary,
 // but saves a lot of boilerplate, offers a lot of features and guardrails,
 // and makes your test setup more declarative and easy to read:
 //
-//   - SuiteManager lets you specify groups of files to treat as test data.
-//   - SuiteManager lets you associate TestingPattern callbacks with hunk names by globbing.
-//   - SuiteManager automatically names your tests based on the filename and hunk names.
-//   - SuiteManager automatically rigs up fixture regeneration for you when `-testmark.regen=true`.
-//   - SuiteManager will warn you about any hunks that go unused in a file (helps detect typos!).
-//   - SuiteManager will warn you about any hunk globs that go unmatched in a file.
+//   - suite.Manager lets you specify groups of files to treat as test data.
+//   - suite.Manager lets you associate TestingFunctor callbacks with hunk names by globbing.
+//   - suite.Manager automatically names your tests based on the filename and hunk names.
+//   - suite.Manager automatically rigs up fixture regeneration for you when `-testmark.regen=true`.
+//   - suite.Manager will warn you about any hunks that go unused in a file (helps detect typos!).
+//   - suite.Manager will warn you about any hunk globs that go unmatched in a file.
 //
-// In general, using SuiteManager will help make sure your fixture files and test cases
+// In general, using suite.Manager will help make sure your fixture files and test cases
 // stay aligned as the code evolves: if you remove tests that used some hunks, you'll get notified;
 // if you add tests that expect certain patterns of hunks in some files, but didn't write them yet,
 // you'll get notified; etc.
 //
-// Approximately the only thing SuiteManager can't help you with is if you use whole files for organization,
+// Approximately the only thing suite.Manager can't help you with is if you use whole files for organization,
 // and you remove some files (or add some features or tests that would expect whole new files),
-// and you're using globbing to register filenames, then SuiteManager can't help you infer what's missing.
-type SuiteManager struct {
+// and you're using globbing to register filenames, then suite.Manager can't help you infer what's missing.
+type Manager struct {
 	fs fsx.FS
 
 	workset map[string]fileContentExpectations
@@ -54,23 +54,23 @@ type SuiteManager struct {
 type fileContentExpectations struct {
 	filename string
 
-	handlers map[HunkGlob]TestingPattern
+	handlers map[HunkGlob]TestingFunctor
 }
 
-// TestingPattern is the interface that test code should implement to become
-// usable by SuiteManager as a handler.
+// TestingFunctor is the interface that test code should implement to become
+// usable by suite.Manager as a handler.
 //
-// Examples of TestingPattern that are well-known and easy to use immediately
-// include `testexec.TestingPattern`
+// Examples of TestingFunctor that are well-known and easy to use immediately
+// include the one produced by `testexec.NewSuiteTester`.
 //
 // When implementing this interface:
 // The Run method will do the majority of the work.
-// Other methods on the interface let the SuiteManager know how recursion should work,
+// Other methods on the interface let the suite.Manager know how recursion should work,
 // and provide some information that may be used in logging.
 //
 // Note that it is not necessary to import this package in order to implement this interface.
 // Only symbols from testmark's core package and the go standard library are used.
-type TestingPattern interface {
+type TestingFunctor interface {
 	Run(
 		t *testing.T, // The standard testing object, for obvious purposes.
 		filename string, // The filename the subject data was loaded from.  Typically not needed (data comes in via `subject` and, if appropriate, can flow out through `patchAccum`).
@@ -88,19 +88,19 @@ type TestingPattern interface {
 type FilenameGlob string
 type HunkGlob string
 
-// WorkWith registers one or more files to be handled with some TestingPattern.
+// WorkWith registers one or more files to be handled with some TestingFunctor.
 // A globbing pattern can be used for both the filenames, and for what hunk labels
 // within the file should be handled.
 //
 // WorkWith can be called more than one time with the same filename, or with filename
 // globs that cause the same files to be matched more than once.
-// In this case, the mapping of filenames and hunk globs to TestingPattern simply
+// In this case, the mapping of filenames and hunk globs to TestingFunctor simply
 // continue to accumulate.
 //
 // Both filename and hunk label globbing are per `path.Match`.
 // Note that using a "glob" that's a literal, with no actual pattern matching markers, is acceptable.
 //
-// The filename glob is matched against the SuiteManager's filesystem immediately.
+// The filename glob is matched against the suite.Manager's filesystem immediately.
 // If it matches no files, an error is returned.
 // (Use MustWorkWith to panic instead.)
 //
@@ -111,7 +111,7 @@ type HunkGlob string
 // the same filename, the last call of WorkWith overrides the earlier one for that pattern.
 // However, if distinct hunk globs later simply happen to match the same hunk label,
 // then both will be called, and the order in which they are called is unspecified.
-func (sm *SuiteManager) WorkWith(files FilenameGlob, hunks HunkGlob, action TestingPattern) error {
+func (sm *Manager) WorkWith(files FilenameGlob, hunks HunkGlob, action TestingFunctor) error {
 	_, err := path.Match(string(hunks), "")
 	if err != nil {
 		return fmt.Errorf("hunk label glob does not compile: %w", err)
@@ -127,7 +127,7 @@ func (sm *SuiteManager) WorkWith(files FilenameGlob, hunks HunkGlob, action Test
 		if _, exists := sm.workset[match]; !exists {
 			sm.workset[match] = fileContentExpectations{
 				filename: match,
-				handlers: make(map[HunkGlob]TestingPattern),
+				handlers: make(map[HunkGlob]TestingFunctor),
 			}
 		}
 		sm.workset[match].handlers[hunks] = action
@@ -136,7 +136,7 @@ func (sm *SuiteManager) WorkWith(files FilenameGlob, hunks HunkGlob, action Test
 }
 
 // MustWorkWith is exactly as per WorkWith, but panics in case of errors.
-func (sm *SuiteManager) MustWorkWith(files FilenameGlob, hunks HunkGlob, action TestingPattern) {
+func (sm *Manager) MustWorkWith(files FilenameGlob, hunks HunkGlob, action TestingFunctor) {
 	if err := sm.WorkWith(files, hunks, action); err != nil {
 		panic(err)
 	}
@@ -149,24 +149,24 @@ func (sm *SuiteManager) MustWorkWith(files FilenameGlob, hunks HunkGlob, action
 //
 // Such a setup would allow you to put comment nodes even deep inside hunk trees that are used
 // by other test patterns (such as e.g. `testexec.TestPattern`) which would otherwise report them as an error.
-func (sm *SuiteManager) IgnoreUnrecognized(files FilenameGlob, pattern HunkGlob) {
-	panic("not yet implemented") // TODO
-}
+// func (sm *Manager) IgnoreUnrecognized(files FilenameGlob, pattern HunkGlob) {
+// panic("not yet implemented") // TODO
+// }
 
 // Run launches the test suite.
 // WorkWith should have been called to populate the suite before this.
 //
 // Subtests will be created with `t.Run` for each file,
-// and another nested subtest for each hunk that matches and causes
-// a TestingPattern to be invoked.
-// (The TestingPattern gets full control of `t` thereafter, and may
+// and another nested subtest for each hunk that matches a pattern the suite works with
+// and thus causes a TestingFunctor to be invoked.
+// (The TestingFunctor gets full control of `t` thereafter, and may
 // create even further additional subtests.)
 //
 // By default, each file that the suite works with will be handled in parallel,
 // and within each file, the hunks are handled in the order they appear.
 //
 // Calling Run more than one time is nonsensical.
-func (sm *SuiteManager) Run(t *testing.T) {
+func (sm *Manager) Run(t *testing.T) {
 	for filename, fileContentExpectations := range sm.workset {
 		filename := filename
 		fileContentExpectations := fileContentExpectations
@@ -209,7 +209,7 @@ func (sm *SuiteManager) Run(t *testing.T) {
 			reportUnrecog := func(hunkName string, reason string) { unrecognizedHunks[hunkName] = reason }
 
 			// Range over the hunks, treating labels as if they're filesystem paths (e.g., "/" groups them).
-			// For every match, create a subtest with the hunk path as a name, and call the test pattern.
+			// For every match, create a subtest with the hunk path as a name, and call the test functor's Run method.
 			for _, ent := range tmDoc.DirEnt.ChildrenList {
 				// Check every handler associated with this filename if it matches this hunk.
 				for hunkGlob, action := range fileContentExpectations.handlers {
diff --git a/testexec/testpattern_test.go b/testexec/testpattern_test.go
index e4014e2..8bc3b10 100644
--- a/testexec/testpattern_test.go
+++ b/testexec/testpattern_test.go
@@ -8,13 +8,13 @@ import (
 	"github.com/warpfork/go-testmark/testexec"
 )
 
-// Assert that our testingPattern type matches the suite.TestingPattern interface.
+// Assert that our SuiteTester type matches the suite.TestingFunctor interface.
 // By doing this in a "_test.go" file, we avoid importing the suite package in the testexec package.
-var _ suite.TestingPattern = testexec.SuiteTester{}
+var _ suite.TestingFunctor = testexec.SuiteTester{}
 
 func TestSuiteMode(t *testing.T) {
 	t.Run("selfexericse file", func(t *testing.T) {
-		sm := suite.NewSuiteManager(osfs.DirFS("."))
+		sm := suite.NewManager(osfs.DirFS("."))
 		sm.MustWorkWith("selfexercise.md", "*", testexec.NewSuiteTester(testexec.Tester{}))
 		sm.Run(t)
 	})
@@ -22,7 +22,7 @@ func TestSuiteMode(t *testing.T) {
 		if !(*RunFailTest) {
 			t.Skipf("%s requires %q flag to execute", t.Name(), "run-fail-test")
 		}
-		sm := suite.NewSuiteManager(osfs.DirFS("."))
+		sm := suite.NewManager(osfs.DirFS("."))
 		sm.MustWorkWith("strictexercise.md", "*", testexec.NewSuiteTester(testexec.Tester{}))
 		sm.Run(t)
 	})