Skip to content

Commit 9a9304a

Browse files
committed
fix(gnolang#4178): add twin test checking
1 parent 8f2cb72 commit 9a9304a

File tree

1 file changed

+84
-33
lines changed

1 file changed

+84
-33
lines changed

gnovm/pkg/test/test.go

Lines changed: 84 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,51 @@ func tee(ptr *io.Writer, dst io.Writer) (revert func()) {
203203
}
204204
}
205205

206+
// an empty type
207+
type void struct{}
208+
209+
// a set of string, to only check for string containing
210+
type stringSet map[string]void
211+
212+
// remove the '_filetest' and '_test' extensions
213+
// example: when 'foo_test.gno' is given, you get 'foo.gno'
214+
func cleanTestFilename(name string) string {
215+
// get the extension
216+
ext := ""
217+
for i := len(name) - 1; i >= 0; i-- {
218+
if name[i] == '.' {
219+
ext = name[i:]
220+
name = name[:i]
221+
break
222+
}
223+
}
224+
225+
// remove the suffix
226+
if len(name) >= 9 && name[len(name)-9:] == "_filetest" {
227+
name = name[:len(name)-9]
228+
} else if len(name) >= 5 && name[len(name)-5:] == "_test" {
229+
name = name[:len(name)-5]
230+
}
231+
return name + ext
232+
}
233+
234+
// check for filetests and tests files if they have there matching twin.
235+
// example: 'foo_test.gno' should have 'foo.gno'
236+
func (opts *TestOptions) removeNonTwinTests(rset stringSet, set *gno.FileSet) {
237+
n := 0
238+
for _, x := range set.Files {
239+
rgFile := cleanTestFilename(string(x.Name))
240+
_, ok := rset[rgFile]
241+
if ok {
242+
set.Files = append(set.Files, x)
243+
n++
244+
} else {
245+
fmt.Fprintf(opts.Error, "=== \x1b[33mWARN\x1b[m '%s' does not have a matching candidate ('%s'). Test file is ignored.\n", x.Name, rgFile)
246+
}
247+
}
248+
set.Files = set.Files[:n]
249+
}
250+
206251
// Test runs tests on the specified memPkg.
207252
// fsDir is the directory on filesystem of package; it's used in case opts.Sync
208253
// is enabled, and points to the directory where the files are contained if they
@@ -223,7 +268,11 @@ func Test(memPkg *gnovm.MemPackage, fsDir string, opts *TestOptions) error {
223268
// Stands for "test", "integration test", and "filetest".
224269
// "integration test" are the test files with `package xxx_test` (they are
225270
// not necessarily integration tests, it's just for our internal reference.)
226-
tset, itset, itfiles, ftfiles := parseMemPackageTests(memPkg)
271+
tset, itset, rset, itfiles, ftfiles := parseMemPackageTests(memPkg)
272+
273+
// Remove the tests if there is no regular files linked to it
274+
opts.removeNonTwinTests(rset, tset)
275+
opts.removeNonTwinTests(rset, itset)
227276

228277
// Testing with *_test.gno
229278
if len(tset.Files)+len(itset.Files) > 0 {
@@ -258,41 +307,42 @@ func Test(memPkg *gnovm.MemPackage, fsDir string, opts *TestOptions) error {
258307

259308
// Testing with *_filetest.gno.
260309
if len(ftfiles) > 0 {
261-
filter := splitRegexp(opts.RunFlag)
262-
for _, testFile := range ftfiles {
263-
testFileName := testFile.Name
264-
testFilePath := filepath.Join(fsDir, testFileName)
265-
testName := "file/" + testFileName
266-
if !shouldRun(filter, testName) {
267-
continue
268-
}
269-
270-
startedAt := time.Now()
271-
if opts.Verbose {
272-
fmt.Fprintf(opts.Error, "=== RUN %s\n", testName)
273-
}
310+
return errs
311+
}
312+
filter := splitRegexp(opts.RunFlag)
313+
for _, testFile := range ftfiles {
314+
testFileName := testFile.Name
315+
testFilePath := filepath.Join(fsDir, testFileName)
316+
testName := "file/" + testFileName
317+
if !shouldRun(filter, testName) {
318+
continue
319+
}
274320

275-
changed, err := opts.runFiletest(testFileName, []byte(testFile.Body))
276-
if changed != "" {
277-
// Note: changed always == "" if opts.Sync == false.
278-
err = os.WriteFile(testFilePath, []byte(changed), 0o644)
279-
if err != nil {
280-
panic(fmt.Errorf("could not fix golden file: %w", err))
281-
}
282-
}
321+
startedAt := time.Now()
322+
if opts.Verbose {
323+
fmt.Fprintf(opts.Error, "=== RUN %s\n", testName)
324+
}
283325

284-
duration := time.Since(startedAt)
285-
dstr := fmtDuration(duration)
326+
changed, err := opts.runFiletest(testFileName, []byte(testFile.Body))
327+
if changed != "" {
328+
// Note: changed always == "" if opts.Sync == false.
329+
err = os.WriteFile(testFilePath, []byte(changed), 0o644)
286330
if err != nil {
287-
fmt.Fprintf(opts.Error, "--- FAIL: %s (%s)\n", testName, dstr)
288-
fmt.Fprintln(opts.Error, err.Error())
289-
errs = multierr.Append(errs, fmt.Errorf("%s failed", testName))
290-
} else if opts.Verbose {
291-
fmt.Fprintf(opts.Error, "--- PASS: %s (%s)\n", testName, dstr)
331+
panic(fmt.Errorf("could not fix golden file: %w", err))
292332
}
333+
}
293334

294-
// XXX: add per-test metrics
335+
duration := time.Since(startedAt)
336+
dstr := fmtDuration(duration)
337+
if err != nil {
338+
fmt.Fprintf(opts.Error, "--- FAIL: %s (%s)\n", testName, dstr)
339+
fmt.Fprintln(opts.Error, err.Error())
340+
errs = multierr.Append(errs, fmt.Errorf("%s failed", testName))
341+
} else if opts.Verbose {
342+
fmt.Fprintf(opts.Error, "--- PASS: %s (%s)\n", testName, dstr)
295343
}
344+
345+
// XXX: add per-test metrics
296346
}
297347

298348
return errs
@@ -365,7 +415,7 @@ func (opts *TestOptions) runTestFiles(
365415
}
366416
if err != nil {
367417
p = filepath.Join(opts.RootDir, "examples", ppath, name)
368-
b, err = os.ReadFile(p)
418+
b, _ = os.ReadFile(p)
369419
}
370420
return string(b)
371421
}
@@ -473,9 +523,10 @@ func loadTestFuncs(pkgName string, tfiles *gno.FileSet) (rt []testFunc) {
473523
}
474524

475525
// parseMemPackageTests parses test files (skipping filetests) in the memPkg.
476-
func parseMemPackageTests(memPkg *gnovm.MemPackage) (tset, itset *gno.FileSet, itfiles, ftfiles []*gnovm.MemFile) {
526+
func parseMemPackageTests(memPkg *gnovm.MemPackage) (tset, itset *gno.FileSet, rset stringSet, itfiles, ftfiles []*gnovm.MemFile) {
477527
tset = &gno.FileSet{}
478528
itset = &gno.FileSet{}
529+
rset = stringSet{}
479530
var errs error
480531
for _, mfile := range memPkg.Files {
481532
if !strings.HasSuffix(mfile.Name, ".gno") {
@@ -499,7 +550,7 @@ func parseMemPackageTests(memPkg *gnovm.MemPackage) (tset, itset *gno.FileSet, i
499550
itset.AddFiles(n)
500551
itfiles = append(itfiles, mfile)
501552
case memPkg.Name == string(n.PkgName):
502-
// normal package file
553+
rset[string(n.Name)] = void{}
503554
default:
504555
panic(fmt.Sprintf(
505556
"expected package name [%s] or [%s_test] but got [%s] file [%s]",

0 commit comments

Comments
 (0)