Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New syntax #43

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

`fakedata` is a small command line utility that generates random data.

For questions join the [#fakedata](https://gophers.slack.com/messages/fakedata/) channel in the [Gophers Slack](https://invite.slack.golangbridge.org/).

# Table Of Contents

- [Overview](#overview)
Expand All @@ -15,7 +13,9 @@ For questions join the [#fakedata](https://gophers.slack.com/messages/fakedata/)

# Overview

Here is a list of examples to get a feeling of how `fakedata` works
Here is a list of examples to get a feeling of how `fakedata` works.

You can specify the name of generators you want to use:

```sh
$ fakedata email country
Expand Down Expand Up @@ -79,9 +79,9 @@ Some generators allow you to pass in a range to constraint the output to a
subset of values:

```sh
$ fakedata int,1..100 # will generate only integers between 1 and 100
$ fakedata int,50.. # specifying only min number works too
$ fakedata int,50 # also works
$ fakedata int:1,100 # will generate only integers between 1 and 100
$ fakedata int:50, # specifying only min number works too
$ fakedata int:50 # also works
```

The `enum` generator allows you to specify a set of values. It comes handy when
Expand All @@ -94,7 +94,7 @@ baz
foo
foo
baz
$ fakedata --limit 5 enum,bug..feature..question..duplicate
$ fakedata --limit 5 enum:bug,feature,question,duplicate
question
duplicate
duplicate
Expand All @@ -105,7 +105,7 @@ feature
When passing a single value `enum` can be used to repeat a value in every line:

```sh
$ fakedata --limit 5 enum,one..two enum,repeat
$ fakedata --limit 5 enum:one,two enum,repeat
two repeat
one repeat
two repeat
Expand All @@ -117,7 +117,7 @@ The `file` generator can be use to read custom values from a file:

```sh
$ printf "one\ntwo\nthree" > values.txt
$ fakedata -l5 file,values.txt
$ fakedata -l5 file:values.txt
three
two
two
Expand Down Expand Up @@ -162,9 +162,9 @@ $ brew install lucapette/tap/fakedata

## Standalone

`fakedata` can be installed as an executable. Download the latest
[compiled binaries](https://github.com/lucapette/fakedata/releases) and put it
anywhere in your executable path.
`fakedata` can be installed as an executable. Download the latest [compiled
binary](https://github.com/lucapette/fakedata/releases) and put it anywhere in
your executable path.

## Source

Expand All @@ -180,10 +180,12 @@ We love every form of contribution! Good entry points to the project are:
[gardening](https://github.com/lucapette/fakedata/issues?q=is%3Aissue+is%3Aopen+label%3Agardening)
- Issues with the tag [good first
patch](https://github.com/lucapette/fakedata/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+patch%22)
- Join the [#fakedata](https://gophers.slack.com/messages/fakedata/) channel in
the [Gophers Slack](https://invite.slack.golangbridge.org/).

If you're still not sure where to start, please open a [new
issue](https://github.com/lucapette/fakedata/issues/new) and we'll gladly
help you get started.
If you're not sure where to start, please open a [new
issue](https://github.com/lucapette/fakedata/issues/new) and we'll gladly help
you get started.

# Code of Conduct

Expand Down
26 changes: 13 additions & 13 deletions integration/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func TestCliArgs(t *testing.T) {
},
{
name: "default format",
args: []string{"int,42..42", "enum,foo..foo"},
args: []string{"int:42,42", "enum:foo,foo"},
fixture: "default-format.golden",
},
{
Expand All @@ -82,42 +82,42 @@ func TestCliArgs(t *testing.T) {
},
{
name: "default format with limit short",
args: []string{"-l=5", "int,42..42", "enum,foo..foo"},
args: []string{"-l=5", "int:42,42", "enum:foo,foo"},
fixture: "default-format-with-limit.golden",
},
{
name: "default format with limit",
args: []string{"--limit=5", "int,42..42", "enum,foo..foo"},
args: []string{"--limit=5", "int:42,42", "enum:foo,foo"},
fixture: "default-format-with-limit.golden",
},
{
name: "csv format short",
args: []string{"-f=csv", "int,42..42", "enum,foo..foo"},
args: []string{"-f=csv", "int:42,42", "enum:foo,foo"},
fixture: "csv-format.golden",
},
{
name: "csv format",
args: []string{"--format=csv", "int,42..42", "enum,foo..foo"},
args: []string{"--format=csv", "int:42,42", "enum:foo,foo"},
fixture: "csv-format.golden",
},
{
name: "tab format",
args: []string{"-f=tab", "int,42..42", "enum,foo..foo"},
args: []string{"-f=tab", "int:42,42", "enum:foo,foo"},
fixture: "tab-format.golden",
},
{
name: "sql format",
args: []string{"-f=sql", "int,42..42", "enum,foo..foo"},
args: []string{"-f=sql", "int:42,42", "enum:foo,foo"},
fixture: "sql-format.golden",
},
{
name: "sql format with keys",
args: []string{"-f=sql", "age=int,42..42", "name=enum,foo..foo"},
args: []string{"-f=sql", "age=int:42,42", "name=enum:foo,foo"},
fixture: "sql-format-with-keys.golden",
},
{
name: "sql format with table name",
args: []string{"-f=sql", "-t=USERS", "int,42..42", "enum,foo..foo"},
args: []string{"-f=sql", "-t=USERS", "int:42,42", "enum:foo,foo"},
fixture: "sql-format-with-table-name.golden",
},
}
Expand Down Expand Up @@ -152,10 +152,10 @@ func TestFileGenerator(t *testing.T) {
wantErr bool
}{
{"no file", []string{"file"}, "path-empty.golden", true},
{"no file,", []string{"file,"}, "path-empty.golden", true},
{"file does not exist", []string{`file,'this file does not exist.txt'`}, "file-empty.golden", true},
{"file exists", []string{`file,integration/file.txt`}, "file-exist.golden", false},
{"file exists with quotes", []string{`file,'integration/file.txt'`}, "file-exist.golden", false},
{"no file,", []string{"file:"}, "path-empty.golden", true},
{"file does not exist", []string{`file:'this file does not exist.txt'`}, "file-empty.golden", true},
{"file exists", []string{`file:integration/file.txt`}, "file-exist.golden", false},
{"file exists with quotes", []string{`file:'integration/file.txt'`}, "file-exist.golden", false},
}

for _, tt := range tests {
Expand Down
6 changes: 3 additions & 3 deletions integration/generators.golden
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
color one word color
country Full country name
country.code 2-digit country code
date YYYY-MM-DD. Accepts a range in the format YYYY-MM-DD..YYYY-MM-DD. By default, it generates dates in the last year.
date YYYY-MM-DD. Accepts a range in the format YYYY-MM-DD,YYYY-MM-DD. By default, it generates dates in the last year.
domain domain
domain.name example|test
domain.tld name|info|com|org|me|us
double double number
email email
enum a random value from an enum. Defaults to "foo..bar..baz"
enum a random value from an enum. Defaults to "foo,bar,baz"
event.action clicked|purchased|viewed|watched
file Read a random line from a file. Pass filepath with 'file,path/to/file.txt'.
http.method DELETE|GET|HEAD|OPTION|PATCH|POST|PUT
int positive integer. Accepts range min..max (default: 1..1000).
int positive integer. Accepts range min..max (default: 1,1000).
ipv4 ipv4
ipv6 ipv6
latitude latitude
Expand Down
10 changes: 5 additions & 5 deletions pkg/fakedata/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (

// A Column represents one field of data to generate
type Column struct {
Name string
Key string
Constraints string
Name string
Key string
Options string
}

func (c *Column) String() string {
Expand All @@ -27,10 +27,10 @@ func NewColumns(keys []string) (cols Columns, err error) {
var errors bytes.Buffer

for i, k := range keys {
specs := strings.Split(k, ",")
specs := strings.Split(k, ":")

if len(specs) > 1 {
cols[i].Constraints = specs[1]
cols[i].Options = specs[1]
}

values := strings.Split(specs[0], "=")
Expand Down
113 changes: 69 additions & 44 deletions pkg/fakedata/column_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,83 +7,108 @@ import (
"github.com/lucapette/fakedata/pkg/fakedata"
)

type columnsTests []struct {
name string
input []string
expected fakedata.Columns
wantErr bool
}

func TestNewColumns(t *testing.T) {
tests := []struct {
name string
input []string
expected fakedata.Columns
wantErr bool
}{
{name: "one column", input: []string{"email"}, expected: fakedata.Columns{{Key: "email", Name: "email"}}, wantErr: false},
{name: "two columns", input: []string{"email", "domain"}, expected: fakedata.Columns{{Key: "email", Name: "email"}, {Key: "domain", Name: "domain"}}, wantErr: false},
{name: "two columns, one column fails", input: []string{"email", "domain", "unsupportedgenerator"}, expected: nil, wantErr: true},
{name: "one column, all fails", input: []string{"madeupgenerator"}, expected: nil, wantErr: true},
tests := columnsTests{
{
name: "one column",
input: []string{"email"},
expected: fakedata.Columns{{Key: "email", Name: "email"}},
wantErr: false,
},
{
name: "two columns",
input: []string{"email", "domain"},
expected: fakedata.Columns{{Key: "email", Name: "email"}, {Key: "domain", Name: "domain"}},
wantErr: false,
},
{
name: "two columns, one column fails",
input: []string{"email", "domain", "unsupportedgenerator"},
wantErr: true,
},
{
name: "one column, all fails",
input: []string{"madeupgenerator"},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual, err := fakedata.NewColumns(tt.input)

// Test fails with unexpected result
if !reflect.DeepEqual(actual, tt.expected) && !tt.wantErr {
t.Errorf("NewColumns() = %v, want %v", actual, tt.expected)
if (err != nil) != tt.wantErr {
t.Errorf("wanted err to be %v but got %v. err: %v", tt.wantErr, (err != nil), err)
}

// Dont't want error but got error
if (err != nil) && !tt.wantErr {
t.Errorf("NewColumns() = Dont want error but got: %v", err)
if !tt.wantErr && !reflect.DeepEqual(actual, tt.expected) {
t.Errorf("expected %v to equal %v", actual, tt.expected)
}
})
}
}

func TestNewColumnsWithName(t *testing.T) {
tests := []struct {
name string
input []string
expected fakedata.Columns
wantErr bool
}{
{name: "one column", input: []string{"login=email"}, expected: fakedata.Columns{{Key: "email", Name: "login"}}, wantErr: false},
{name: "one column, unupported generator", input: []string{"login=notagen"}, expected: nil, wantErr: true},
tests := columnsTests{
{
name: "one column",
input: []string{"login=email"},
expected: fakedata.Columns{{Key: "email", Name: "login"}},
wantErr: false,
},
{
name: "one column, unsupported generator",
input: []string{"login=notagen"},
expected: fakedata.Columns{},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual, err := fakedata.NewColumns(tt.input)
// Test fails with unexpected result
if !reflect.DeepEqual(actual, tt.expected) && !tt.wantErr {
t.Errorf("NewColumns() = %v, want %v", actual, tt.expected)

if (err != nil) != tt.wantErr {
t.Errorf("wanted err to be %v but got %v. err: %v", tt.wantErr, (err != nil), err)
}

// Dont't want error but got error
if (err != nil) && !tt.wantErr {
t.Errorf("NewColumns() = Dont want error but got: %v", err)
if !tt.wantErr && !reflect.DeepEqual(actual, tt.expected) {
t.Errorf("expected %v to equal %v", actual, tt.expected)
}
})
}
}

func TestNewColumnsWithSpec(t *testing.T) {
tests := []struct {
name string
input []string
expected fakedata.Columns
wantErr bool
}{
{name: "int full range", input: []string{"int,1..100"}, expected: fakedata.Columns{{Key: "int", Name: "int", Constraints: "1..100"}}, wantErr: false},
{name: "int lower bound", input: []string{"int,1.."}, expected: fakedata.Columns{{Key: "int", Name: "int", Constraints: "1.."}}, wantErr: false},
tests := columnsTests{
{
name: "int full range",
input: []string{"int:1,100"},
expected: fakedata.Columns{{Key: "int", Name: "int", Options: "1,100"}},
wantErr: false,
},
{
name: "int lower bound",
input: []string{"int:1,"},
expected: fakedata.Columns{{Key: "int", Name: "int", Options: "1,"}},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual, err := fakedata.NewColumns(tt.input)

// Test fails with unexpected result
if !reflect.DeepEqual(actual, tt.expected) && !tt.wantErr {
t.Errorf("NewColumns() = %v, want %v", actual, tt.expected)
if (err != nil) != tt.wantErr {
t.Errorf("wanted err to be %v but got %v. err: %v", tt.wantErr, (err != nil), err)
}

// Dont't want error but got error
if (err != nil) && !tt.wantErr {
t.Errorf("NewColumns() = Dont want error but got: %v", err)
if !tt.wantErr && !reflect.DeepEqual(actual, tt.expected) {
t.Errorf("expected %v to equal %v", actual, tt.expected)
}
})
}
Expand Down
Loading