Skip to content

Commit

Permalink
refactoring to allow adding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
coryb committed Nov 8, 2020
1 parent 50e71d6 commit a2a0d23
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 164 deletions.
69 changes: 46 additions & 23 deletions slipscheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
Expand Down Expand Up @@ -111,14 +112,31 @@ func (s *SchemaType) MarshalJSON() ([]byte, error) {
}

func main() {
outputDir := flag.String("dir", ".", "output directory for go files")
pkgName := flag.String("pkg", "main", "package namespace for go files")
overwrite := flag.Bool("overwrite", false, "force overwriting existing go files")
stdout := flag.Bool("stdout", false, "print go code to stdout rather than files")
format := flag.Bool("fmt", true, "pass code through gofmt")
comments := flag.Bool("comments", true, "enable/disable print comments")
exitCode := Main(os.Args, Stdio{
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
})
os.Exit(exitCode)
}

type Stdio struct {
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
}

func Main(arguments []string, io Stdio) int {
flags := flag.NewFlagSet(arguments[0], flag.ExitOnError)
outputDir := flags.String("dir", ".", "output directory for go files")
pkgName := flags.String("pkg", "main", "package namespace for go files")
overwrite := flags.Bool("overwrite", false, "force overwriting existing go files")
stdout := flags.Bool("stdout", false, "print go code to stdout rather than files")
format := flags.Bool("fmt", true, "pass code through gofmt")
comments := flags.Bool("comments", true, "enable/disable print comments")

flag.Parse()
flags.SetOutput(io.Stderr)
flags.Parse(arguments[1:])

processor := &SchemaProcessor{
OutputDir: *outputDir,
Expand All @@ -127,19 +145,22 @@ func main() {
Stdout: *stdout,
Fmt: *format,
Comment: *comments,
IO: io,
}

args := flag.Args()
args := flags.Args()
if len(args) == 0 {
fmt.Fprintf(os.Stderr, "Usage: %s <schema file> [<schema file> ...]\n", os.Args[0])
flag.PrintDefaults()
os.Exit(1)
flags.SetOutput(io.Stdout)
fmt.Fprintf(io.Stdout, "Usage: %s <schema file> [<schema file> ...]\n", arguments[0])
flags.PrintDefaults()
return 0
}
err := processor.Process(args)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %s\n", err)
os.Exit(1)
fmt.Fprintf(io.Stderr, "Error: %s\n", err)
return 1
}
return 0
}

// SchemaProcessor object used to convert json schemas to golang structs
Expand All @@ -151,24 +172,26 @@ type SchemaProcessor struct {
Fmt bool
Comment bool
processed map[string]bool
IO Stdio
}

// Process will read a list of json schema files, parse them
// and write them to the OutputDir
func (s *SchemaProcessor) Process(files []string) error {
for _, file := range files {
var fh *os.File
var r io.Reader
var b []byte
if file == "-" {
fh = os.Stdin
r = s.IO.Stdin
} else {
var err error
fh, err = os.OpenFile(file, os.O_RDONLY, 0644)
fh, err := os.OpenFile(file, os.O_RDONLY, 0644)
defer fh.Close()
if err != nil {
return err
}
r = fh
}
b, err := ioutil.ReadAll(fh)
b, err := ioutil.ReadAll(r)
if err != nil {
return err
}
Expand Down Expand Up @@ -383,8 +406,8 @@ func (s *SchemaProcessor) writeGoCode(typeName, code string) error {
if s.Fmt {
cmd := exec.Command("gofmt", "-s")
inPipe, _ := cmd.StdinPipe()
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdout = s.IO.Stdout
cmd.Stderr = s.IO.Stderr
cmd.Start()
inPipe.Write([]byte(code))
inPipe.Close()
Expand Down Expand Up @@ -428,9 +451,9 @@ func (s *SchemaProcessor) writeGoCode(typeName, code string) error {

if s.Fmt {
cmd := exec.Command("gofmt", "-s", "-w", file)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = s.IO.Stdin
cmd.Stdout = s.IO.Stdout
cmd.Stderr = s.IO.Stderr
return cmd.Run()
}
return nil
Expand Down
177 changes: 177 additions & 0 deletions slipscheme_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package main

import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
)

func ExampleUsage() {
Main([]string{"slipscheme"}, Stdio{
Stdout: os.Stdout,
})
// Output:
// Usage: slipscheme <schema file> [<schema file> ...]
// -comments
// enable/disable print comments (default true)
// -dir string
// output directory for go files (default ".")
// -fmt
// pass code through gofmt (default true)
// -overwrite
// force overwriting existing go files
// -pkg string
// package namespace for go files (default "main")
// -stdout
// print go code to stdout rather than files
}

func TestOutputFiles(t *testing.T) {
tdir, err := ioutil.TempDir("", "slipscheme")
noError(t, err)
Main([]string{"slipscheme", "-dir", tdir, "sample.json"}, Stdio{
Stdout: os.Stdout,
})
exists(t, filepath.Join(tdir, "Contact.go"))
exists(t, filepath.Join(tdir, "Address.go"))
exists(t, filepath.Join(tdir, "Phone.go"))
exists(t, filepath.Join(tdir, "Phones.go"))
}

func ExampleStdoutSlice() {
input := `{
"title": "stuff",
"type": "array",
"items": {
"type": "string"
}
}`
Main([]string{"slipscheme", "-stdout=true", "-"}, Stdio{
Stdin: strings.NewReader(input),
Stdout: os.Stdout,
})

// Output:
// // Stuff defined from schema:
// // {
// // "title": "stuff",
// // "type": "array",
// // "items": {
// // "type": "string"
// // }
// // }
// type Stuff []string
}

func ExampleNoComments() {
input := `{
"title": "stuff",
"type": "array",
"items": {
"type": "string"
}
}`
Main([]string{"slipscheme", "-stdout=true", "-comments=false", "-"}, Stdio{
Stdin: strings.NewReader(input),
Stdout: os.Stdout,
})

// Output:
// type Stuff []string
}

func ExampleStruct() {
input := `{
"title": "thing",
"type": "object",
"properties": {
"this": {
"type": "integer"
},
"that": {
"type": "string"
}
}
}`
Main([]string{"slipscheme", "-stdout=true", "-comments=false", "-"}, Stdio{
Stdin: strings.NewReader(input),
Stdout: os.Stdout,
})

// Output:
// type Thing struct {
// That string `json:"that,omitempty" yaml:"that,omitempty"`
// This int `json:"this,omitempty" yaml:"this,omitempty"`
// }
}

func ExampleNoFmt() {
input := `{
"title": "thing",
"type": "object",
"properties": {
"this": {
"type": "integer"
},
"that": {
"type": "string"
}
}
}`
Main([]string{"slipscheme", "-stdout=true", "-comments=false", "-fmt=false", "-"}, Stdio{
Stdin: strings.NewReader(input),
Stdout: os.Stdout,
})

// Output:
// type Thing struct {
// That string `json:"that,omitempty" yaml:"that,omitempty"`
// This int `json:"this,omitempty" yaml:"this,omitempty"`
// }
}

func ExampleStructSlice() {
input := `{
"title": "stuff",
"type": "array",
"items": {
"title": "thing",
"type": "object",
"properties": {
"this": {
"type": "integer"
},
"that": {
"type": "string"
}
}
}
}`
Main([]string{"slipscheme", "-stdout=true", "-comments=false", "-"}, Stdio{
Stdin: strings.NewReader(input),
Stdout: os.Stdout,
})

// Output:
// type Thing struct {
// That string `json:"that,omitempty" yaml:"that,omitempty"`
// This int `json:"this,omitempty" yaml:"this,omitempty"`
// }

// type Stuff []*Thing
}

func noError(t *testing.T, err error) {
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
}

func exists(t *testing.T, file string) {
_, err := os.Stat(file)
if err != nil {
t.Fatalf("Failed to test for file existence on %s: %s", file, err)
}
}
Loading

0 comments on commit a2a0d23

Please sign in to comment.