Skip to content

Commit

Permalink
Merge branch 'master' into vladimirvivien-bugfix/array-tables
Browse files Browse the repository at this point in the history
  • Loading branch information
pelletier committed Aug 15, 2016
2 parents df0392f + de2e921 commit 0d08b47
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 2 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,23 @@ if err != nil {
The documentation and additional examples are available at
[godoc.org](http://godoc.org/github.com/pelletier/go-toml).

## Tools

Go-toml provides two handy command line tools:

* `tomll`: Reads TOML files and lint them.

```
go install github.com/pelletier/go-toml/cmd/tomll
tomll --help
```
* `tomljson`: Reads a TOML file and outputs its JSON representation.

```
go install github.com/pelletier/go-toml/cmd/tomjson
tomljson --help
```

## Contribute

Feel free to report bugs and patches using GitHub's pull requests system on
Expand Down
66 changes: 66 additions & 0 deletions cmd/tomljson/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package main

import (
"github.com/pelletier/go-toml"
"io"
"os"
"flag"
"fmt"
"encoding/json"
)

func main() {
flag.Usage = func() {
fmt.Fprintln(os.Stderr, `tomljson can be used in two ways:
Writing to STDIN and reading from STDOUT:
cat file.toml | tomljson > file.json
Reading from a file name:
tomljson file.toml
`)
}
flag.Parse()
os.Exit(processMain(flag.Args(), os.Stdin, os.Stdout, os.Stderr))
}

func processMain(files []string, defaultInput io.Reader, output io.Writer, errorOutput io.Writer) int {
// read from stdin and print to stdout
inputReader := defaultInput

if len(files) > 0 {
var err error
inputReader, err = os.Open(files[0])
if err != nil {
printError(err, errorOutput)
return -1
}
}
s, err := reader(inputReader)
if err != nil {
printError(err, errorOutput)
return -1
}
io.WriteString(output, s + "\n")
return 0
}

func printError(err error, output io.Writer) {
io.WriteString(output, err.Error() + "\n")
}

func reader(r io.Reader) (string, error) {
tree, err := toml.LoadReader(r)
if err != nil {
return "", err
}
return mapToJson(tree)
}

func mapToJson(tree *toml.TomlTree) (string, error) {
treeMap := tree.ToMap()
bytes, err := json.MarshalIndent(treeMap, "", " ")
if err != nil {
return "", err
}
return string(bytes[:]), nil
}
84 changes: 84 additions & 0 deletions cmd/tomljson/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package main

import (
"testing"
"strings"
"bytes"
"os"
"io/ioutil"
)

func expectBufferEquality(t *testing.T, name string, buffer *bytes.Buffer, expected string) {
output := buffer.String()
if output != expected {
t.Errorf("incorrect %s:\n%s\n\nexpected %s:\n%s", name, output, name, expected)
t.Log([]rune(output))
t.Log([]rune(expected))
}
}

func expectProcessMainResults(t *testing.T, input string, args []string, exitCode int, expectedOutput string, expectedError string) {
inputReader := strings.NewReader(input)
outputBuffer := new(bytes.Buffer)
errorBuffer := new(bytes.Buffer)

returnCode := processMain(args, inputReader, outputBuffer, errorBuffer)

expectBufferEquality(t, "output", outputBuffer, expectedOutput)
expectBufferEquality(t, "error", errorBuffer, expectedError)

if returnCode != exitCode {
t.Error("incorrect return code:", returnCode, "expected", exitCode)
}
}


func TestProcessMainReadFromStdin(t *testing.T) {
input := `
[mytoml]
a = 42`
expectedOutput := `{
"mytoml": {
"a": 42
}
}
`
expectedError := ``
expectedExitCode := 0

expectProcessMainResults(t, input, []string{}, expectedExitCode, expectedOutput, expectedError)
}

func TestProcessMainReadFromFile(t *testing.T) {
input := `
[mytoml]
a = 42`


tmpfile, err := ioutil.TempFile("", "example.toml")
if err != nil {
t.Fatal(err)
}
if _, err := tmpfile.Write([]byte(input)); err != nil {
t.Fatal(err)
}

defer os.Remove(tmpfile.Name())

expectedOutput := `{
"mytoml": {
"a": 42
}
}
`
expectedError := ``
expectedExitCode := 0

expectProcessMainResults(t, ``, []string{tmpfile.Name()}, expectedExitCode, expectedOutput, expectedError)
}

func TestProcessMainReadFromMissingFile(t *testing.T) {
expectedError := `open /this/file/does/not/exist: no such file or directory
`
expectProcessMainResults(t, ``, []string{"/this/file/does/not/exist"}, -1, ``, expectedError)
}
5 changes: 3 additions & 2 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ go build -o toml-test github.com/BurntSushi/toml-test
# NOTE: this basically mocks an install without having to go back out to github for code
mkdir -p src/github.com/pelletier/go-toml/cmd
cp *.go *.toml src/github.com/pelletier/go-toml
cp cmd/*.go src/github.com/pelletier/go-toml/cmd
cp -R cmd/* src/github.com/pelletier/go-toml/cmd
go build -o test_program_bin src/github.com/pelletier/go-toml/cmd/test_program.go

# Run basic unit tests
go test -v github.com/pelletier/go-toml
go test github.com/pelletier/go-toml \
github.com/pelletier/go-toml/cmd/tomljson

# run the entire BurntSushi test suite
if [[ $# -eq 0 ]] ; then
Expand Down

0 comments on commit 0d08b47

Please sign in to comment.