...

Source file src/github.com/pelletier/go-toml/v2/cmd/tomltestgen/main.go

Documentation: github.com/pelletier/go-toml/v2/cmd/tomltestgen

     1  // tomltestgen retrieves a given version of the language-agnostic TOML test suite in
     2  // https://github.com/BurntSushi/toml-test and generates go-toml unit tests.
     3  //
     4  // Within the go-toml package, run `go generate`.  Otherwise, use:
     5  //
     6  //	go run github.com/pelletier/go-toml/cmd/tomltestgen -o toml_testgen_test.go
     7  package main
     8  
     9  import (
    10  	"bytes"
    11  	"flag"
    12  	"fmt"
    13  	"go/format"
    14  	"log"
    15  	"os"
    16  	"path/filepath"
    17  	"strconv"
    18  	"strings"
    19  	"text/template"
    20  	"time"
    21  )
    22  
    23  type invalid struct {
    24  	Name  string
    25  	Input string
    26  }
    27  
    28  type valid struct {
    29  	Name    string
    30  	Input   string
    31  	JsonRef string
    32  }
    33  
    34  type testsCollection struct {
    35  	Ref       string
    36  	Timestamp string
    37  	Invalid   []invalid
    38  	Valid     []valid
    39  	Count     int
    40  }
    41  
    42  const srcTemplate = "// Generated by tomltestgen for toml-test ref {{.Ref}} on {{.Timestamp}}\n" +
    43  	"package toml_test\n" +
    44  	" import (\n" +
    45  	"	\"testing\"\n" +
    46  	")\n" +
    47  
    48  	"{{range .Invalid}}\n" +
    49  	"func TestTOMLTest_Invalid_{{.Name}}(t *testing.T) {\n" +
    50  	"	input := {{.Input|gostr}}\n" +
    51  	"	testgenInvalid(t, input)\n" +
    52  	"}\n" +
    53  	"{{end}}\n" +
    54  	"\n" +
    55  	"{{range .Valid}}\n" +
    56  	"func TestTOMLTest_Valid_{{.Name}}(t *testing.T) {\n" +
    57  	"   input := {{.Input|gostr}}\n" +
    58  	"   jsonRef := {{.JsonRef|gostr}}\n" +
    59  	"   testgenValid(t, input, jsonRef)\n" +
    60  	"}\n" +
    61  	"{{end}}\n"
    62  
    63  func kebabToCamel(kebab string) string {
    64  	camel := ""
    65  	nextUpper := true
    66  	for _, c := range kebab {
    67  		if nextUpper {
    68  			camel += strings.ToUpper(string(c))
    69  			nextUpper = false
    70  		} else if c == '-' {
    71  			nextUpper = true
    72  		} else if c == '/' {
    73  			nextUpper = true
    74  			camel += "_"
    75  		} else {
    76  			camel += string(c)
    77  		}
    78  	}
    79  	return camel
    80  }
    81  
    82  func templateGoStr(input string) string {
    83  	return strconv.Quote(input)
    84  }
    85  
    86  var (
    87  	ref = flag.String("r", "master", "git reference")
    88  	out = flag.String("o", "", "output file")
    89  )
    90  
    91  func usage() {
    92  	_, _ = fmt.Fprintf(os.Stderr, "usage: tomltestgen [flags]\n")
    93  	flag.PrintDefaults()
    94  }
    95  
    96  func main() {
    97  	flag.Usage = usage
    98  	flag.Parse()
    99  
   100  	collection := testsCollection{
   101  		Ref:       *ref,
   102  		Timestamp: time.Now().Format(time.RFC3339),
   103  	}
   104  
   105  	dirContent, _ := filepath.Glob("tests/invalid/**/*.toml")
   106  	for _, f := range dirContent {
   107  		filename := strings.TrimPrefix(f, "tests/valid/")
   108  		name := kebabToCamel(strings.TrimSuffix(filename, ".toml"))
   109  
   110  		log.Printf("> [%s] %s\n", "invalid", name)
   111  
   112  		tomlContent, err := os.ReadFile(f)
   113  		if err != nil {
   114  			fmt.Printf("failed to read test file: %s\n", err)
   115  			os.Exit(1)
   116  		}
   117  
   118  		collection.Invalid = append(collection.Invalid, invalid{
   119  			Name:  name,
   120  			Input: string(tomlContent),
   121  		})
   122  		collection.Count++
   123  	}
   124  
   125  	dirContent, _ = filepath.Glob("tests/valid/**/*.toml")
   126  	for _, f := range dirContent {
   127  		filename := strings.TrimPrefix(f, "tests/valid/")
   128  		name := kebabToCamel(strings.TrimSuffix(filename, ".toml"))
   129  
   130  		log.Printf("> [%s] %s\n", "valid", name)
   131  
   132  		tomlContent, err := os.ReadFile(f)
   133  		if err != nil {
   134  			fmt.Printf("failed reading test file: %s\n", err)
   135  			os.Exit(1)
   136  		}
   137  
   138  		filename = strings.TrimSuffix(f, ".toml")
   139  		jsonContent, err := os.ReadFile(filename + ".json")
   140  		if err != nil {
   141  			fmt.Printf("failed reading validation json: %s\n", err)
   142  			os.Exit(1)
   143  		}
   144  
   145  		collection.Valid = append(collection.Valid, valid{
   146  			Name:    name,
   147  			Input:   string(tomlContent),
   148  			JsonRef: string(jsonContent),
   149  		})
   150  		collection.Count++
   151  	}
   152  
   153  	log.Printf("Collected %d tests from toml-test\n", collection.Count)
   154  
   155  	funcMap := template.FuncMap{
   156  		"gostr": templateGoStr,
   157  	}
   158  	t := template.Must(template.New("src").Funcs(funcMap).Parse(srcTemplate))
   159  	buf := new(bytes.Buffer)
   160  	err := t.Execute(buf, collection)
   161  	if err != nil {
   162  		panic(err)
   163  	}
   164  	outputBytes, err := format.Source(buf.Bytes())
   165  	if err != nil {
   166  		panic(err)
   167  	}
   168  
   169  	if *out == "" {
   170  		fmt.Println(string(outputBytes))
   171  		return
   172  	}
   173  
   174  	err = os.WriteFile(*out, outputBytes, 0o644)
   175  	if err != nil {
   176  		panic(err)
   177  	}
   178  }
   179  

View as plain text