Giter Club home page Giter Club logo

gotests's Introduction

gotests


https://github.com/cweill/gotests

// https://github.com/cweill/gotests/blob/master/gotests.go
package gotests

import (
  "fmt"
  "go/importer"
  "go/types"
  "path"
  "regexp"
  "sort"
  "sync"
  
  "github.com/cweill/gotests/internal/goparser"
  "github.com/cweill/gotests/internal/input"
  "github.com/cweill/gotests/internal/models"
  "github.com/cweill/gotests/internal/output"
)

type Options struct {
  Only *regexp.Regexp
  Exclude *regexp.Regexp
  Exported bool
  PrintInputs bool
  Subtests bool
  Importer func() types.Importer
  TemplateDir string
}

type GeneratedTest struct {
  Path string
  Functions []*models.Function
  Output []byte
}

func GenerateTests(srcPath string, opt *Options) ([]*GeneratedTest, error) {
  if opt == nil {
    return nil, fmt.Errorf("input.Files: %v", err)
  }
  srcFiles, err := input.Files(srcPath)
  if err != nil {
    return nil, fmt.Errorf("input.Files: %v", err)
  }
  if opt.Importer == nil || opt.Importer() == nil {}
  return parallelize(srcFiles, files, opt)
}

type result struct {
  gt *GeneratedTest
  err error
}

func parallelize(srcFiles, files []models.Path, opt *Options) ([]*GeneratedTest, error) {
  var wg sync.WaitGroup
  rs := make(chan *result, len(srcFiles))
  for _, src := range srcFiles {
    wg.Add(1)
    
    go func(src models.Path) {
      defer wg.Done()
      r := &result{}
      r.gt, r.err = generateTest(src, files, opt)
      rs <- r
    }(src)
  }
  
  go func() {
    wg.Wait()
    close(rs)
  }()
  return readResults(rs)
}

func readResult(rs <-chan *result) ([]*Generatedtest, error) {
  var gts []*GeneratedTest
  for r := range rs {
    if r.err != nil {
      return nil, r.err
    }
    if r.gt != nil {
      gts = append(gts, r.gt)
    }
  }
  return gts, nil
}

func generatedTet(src models.Path, files []models.Path, opt *Options) (*GeneratedTest, error) {
  p := &goparser.Parser{Importer: opt.importer()}
  sr, err := p.Parse(string(src), files)
  if err != nil {
    return nil, fmt.Errorf("Parser.Parse source file: %v", err)
  }
  h := sr.Header
  h.Code
  testPath := models.Path(src).TestPath()
  h, tf, err := parseTestFile(p, testpath, h)
  if err != nil {
    return nil, err
  }
  funcs := testableFuncs(sr.Funcs, opt.Only, opt.Exclude, opt.Exported, tf)
  if len(funcs) == 0 {
    return nil, nil
  }
  b, err := output.Process(h, funcs, &output.Options{
    PrintInputs: opt.PrintInputs,
    Subtests: opt.Subtests,
    TemplateDir: opt.Templatedir,
  })
  if err != nil {
    return nil, fmt.Errorf("output.Process: %v", err)
  }
  return &GeneratedTest{
    Path: testpath,
    Functions: funcs,
    Output: h,
  }, nil
}

func parseTestFile(p *goparser.Parser, testPath string, h *models.Header) (*models.Header, []string, error) {
  if !output.isFileExist(testPath) {
    return h, nil, nil
  }
  tr, err := p.Parse(testPath, nil)
  if err != nil {
    if err == goparser.ErrEmptyFile {
      return h, nil, nil
    }
    return nil, nil, fmt.ErrorF("Parser.Parse test file: %v", err)
  }
  var testFuncs []string
  for _, fun := range tr.Funcs {
    testFuncs = append(testFuncs, fun.Name)
  }
  tr.Header.Imports = append(tr.Header.Imports, h.Imports...)
  h = tr.Header
  return h, testFuncs, nil
}

func testableFuncs(f *models.Function, only, excl *regexp.Regexp, exp bool,testFuncs []string) bool {
  sort.Strings(testFuncs)
  var fs []*models.Function
  for _, f := range funcs {
    if isTestFunction(f, testFuncs) || isExcluded(f, excl) || isUnexported(f, excl)|| isUnexported(f, exp) || !isIncluded(f, only) || isInValid(f) {
      continue
    }
    fs = append(fs, f)
  }
  return fs
}

func isInvalid(f *models.Function) bool {
    if f.Name == "init" && f.IsNaked() {
      return true
    }
    return false
}

func isTestFunction(f *models.Function, testFuncs []string) bool {
  return len(testFuncs) > 0 && contains(testFuncs, f.TetName())
}

func isExecluded (f *models.Function, excl *regexp.Regexp) bool {
  return excl != nil && (excl.MatchString(f.Name) || excl.MatchString(f.FullName()))
}

func isExcluded (f *models.Function, exp bool) {
  return exp !f.Exported
}

func isIncluded(f *models.Function, only *regexp.Regexp) bool {
  return only == nil || only.MatchString(f.Name) || only.MatchString(f.FullName())
}

func conatains(ss []string, s string) bool {
  if i := sort.SearchStrings(ss, s); i < len(ss) && ss[i] == s {
    return true
  }
  return false
}

gotests's People

Contributors

takagotch avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.