diff --git a/README.md b/README.md
index 9c9f2c4..ba33a19 100644
--- a/README.md
+++ b/README.md
@@ -300,8 +300,10 @@ functions:
- `Odd`
- `Even`
-If you need to create your own loop for advanced templates you can use the `{{ Loop }}` function. This function takes a single integer as parameter which is
-the number of iterations. `Loop` must be used with `range` e.g.
+If you need to create your own loop for advanced templates you can use the `{{ Loop }}` function.
+
+This function takes a single integer as parameter which is the number of
+iterations. `Loop` must be used with `range` e.g.
```html
{{ range Loop 10 }} You're going to see this 10 times! {{ end }}
@@ -316,11 +318,12 @@ example:
```
In combination with `Loop` and `range` you can use `Odd` and `Even` to determine
-if the current iteration is odd or even. This is especially helpful when
-creating HTML tables:
+if the current iteration is odd or even.
+
+For example, this is helpful when creating HTML tables:
```html
-{{ range $i, $j := Loop 5 }}
+{{ range $i := Loop 5 }}
{{ if Odd $i -}}
{{- else -}} |
@@ -334,8 +337,10 @@ creating HTML tables:
values of `Loop 5` to the variables `$i` and `$j`.
Templates also support string manipulation via the `printf` function. Using
-`printf` we can create custom output. For example to display a full name in the
-format `Lastname Firstname` instead of `Firstname Lastname`.
+`printf` we can create custom output.
+
+For example, to display a full name in the format `Lastname Firstname` instead
+of `Firstname Lastname`.
```html
{{ printf "%s %s" Name.Last Name.First }}
diff --git a/integration/cli_test.go b/integration/cli_test.go
index 12f3553..0f5031b 100644
--- a/integration/cli_test.go
+++ b/integration/cli_test.go
@@ -1,11 +1,7 @@
-package main
+package integration
import (
- "flag"
- "fmt"
- "os"
"os/exec"
- "path/filepath"
"regexp"
"testing"
@@ -14,16 +10,6 @@ import (
"github.com/lucapette/fakedata/testutil"
)
-// In these tests, there's a lot going on. Have a look at this article for a
-// longer explanation:
-// https://lucapette.me/writing/writing-integration-tests-for-a-go-cli-application
-
-var update = flag.Bool("update", false, "update golden files")
-
-const binaryName = "fakedata"
-
-var binaryPath string
-
func TestCLI(t *testing.T) {
tests := []struct {
name string
@@ -199,86 +185,3 @@ func TestFileGenerator(t *testing.T) {
})
}
}
-
-var templateTests = []struct {
- tmpl string
- golden string
- wantErr bool
-}{
- {"simple.tmpl", "simple-template.golden", false},
- {"loop.tmpl", "loop.golden", false},
- {"broken.tmpl", "broken-template.golden", true},
- {"unknown-function.tmpl", "unknown-function.golden", true},
-}
-
-func TestTemplatesWithCLIArgs(t *testing.T) {
- for _, tt := range templateTests {
- t.Run(tt.tmpl, func(t *testing.T) {
- cmd := exec.Command(binaryPath, "--template", fmt.Sprintf("testutil/fixtures/%s", tt.tmpl))
- output, err := cmd.CombinedOutput()
- if (err != nil) != tt.wantErr {
- t.Fatalf("%s\nexpected (err != nil) to be %v, but got %v. err: %v", output, tt.wantErr, err != nil, err)
- }
-
- golden := testutil.NewGoldenFile(t, tt.golden)
- actual := string(output)
- if *update {
- golden.Write(actual)
- }
-
- expected := golden.Load()
-
- if !reflect.DeepEqual(actual, expected) {
- t.Fatalf("diff: %v", testutil.Diff(expected, actual))
- }
- })
- }
-}
-
-func TestTemplatesWithPipe(t *testing.T) {
- for _, tt := range templateTests {
- t.Run(tt.tmpl, func(t *testing.T) {
- fixture := testutil.NewFixture(t, tt.tmpl)
- cmd := exec.Command(binaryPath)
- cmd.Stdin = fixture.AsFile()
- output, err := cmd.CombinedOutput()
- if (err != nil) != tt.wantErr {
- t.Fatalf("%s\nexpected (err != nil) to be %v, but got %v. err: %v", output, tt.wantErr, err != nil, err)
- }
-
- golden := testutil.NewGoldenFile(t, tt.golden)
- actual := string(output)
- if *update {
- golden.Write(actual)
- }
-
- expected := golden.Load()
-
- if !reflect.DeepEqual(actual, expected) {
- t.Fatalf("diff: %v", testutil.Diff(expected, actual))
- }
- })
- }
-}
-
-func TestMain(m *testing.M) {
- err := os.Chdir("..")
- if err != nil {
- fmt.Printf("could not change dir: %v", err)
- os.Exit(1)
- }
-
- abs, err := filepath.Abs(binaryName)
- if err != nil {
- fmt.Printf("could not get abs path for %s: %v", binaryName, err)
- os.Exit(1)
- }
-
- binaryPath = abs
-
- if err := exec.Command("make").Run(); err != nil {
- fmt.Printf("could not make binary for %s: %v", binaryName, err)
- os.Exit(1)
- }
- os.Exit(m.Run())
-}
diff --git a/integration/setup_test.go b/integration/setup_test.go
new file mode 100644
index 0000000..ee9c1b5
--- /dev/null
+++ b/integration/setup_test.go
@@ -0,0 +1,42 @@
+package integration
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "testing"
+)
+
+// In these tests, there's a lot going on. Have a look at this article for a
+// longer explanation:
+// https://lucapette.me/writing/writing-integration-tests-for-a-go-cli-application
+
+var update = flag.Bool("update", false, "update golden files")
+
+const binaryName = "fakedata"
+
+var binaryPath string
+
+func TestMain(m *testing.M) {
+ err := os.Chdir("..")
+ if err != nil {
+ fmt.Printf("could not change dir: %v", err)
+ os.Exit(1)
+ }
+
+ abs, err := filepath.Abs(binaryName)
+ if err != nil {
+ fmt.Printf("could not get abs path for %s: %v", binaryName, err)
+ os.Exit(1)
+ }
+
+ binaryPath = abs
+
+ if err := exec.Command("make").Run(); err != nil {
+ fmt.Printf("could not make binary for %s: %v", binaryName, err)
+ os.Exit(1)
+ }
+ os.Exit(m.Run())
+}
diff --git a/integration/templates_test.go b/integration/templates_test.go
new file mode 100644
index 0000000..960fac5
--- /dev/null
+++ b/integration/templates_test.go
@@ -0,0 +1,72 @@
+package integration
+
+import (
+ "fmt"
+ "os/exec"
+ "reflect"
+ "testing"
+
+ "github.com/lucapette/fakedata/testutil"
+)
+
+var templateTests = []struct {
+ tmpl string
+ golden string
+ wantErr bool
+}{
+ {"simple.tmpl", "simple-template.golden", false},
+ {"loop.tmpl", "loop.golden", false},
+ {"loop-with-index.tmpl", "loop-with-index.golden", false},
+ {"broken.tmpl", "broken-template.golden", true},
+ {"unknown-function.tmpl", "unknown-function.golden", true},
+}
+
+func TestTemplatesWithCLIArgs(t *testing.T) {
+ for _, tt := range templateTests {
+ t.Run(tt.tmpl, func(t *testing.T) {
+ cmd := exec.Command(binaryPath, "--template", fmt.Sprintf("testutil/fixtures/%s", tt.tmpl))
+ output, err := cmd.CombinedOutput()
+ if (err != nil) != tt.wantErr {
+ t.Fatalf("%s\nexpected (err != nil) to be %v, but got %v. err: %v", output, tt.wantErr, err != nil, err)
+ }
+
+ golden := testutil.NewGoldenFile(t, tt.golden)
+ actual := string(output)
+ if *update {
+ golden.Write(actual)
+ }
+
+ expected := golden.Load()
+
+ if !reflect.DeepEqual(actual, expected) {
+ t.Fatalf("diff: %v", testutil.Diff(expected, actual))
+ }
+ })
+ }
+}
+
+func TestTemplatesWithPipe(t *testing.T) {
+ for _, tt := range templateTests {
+ t.Run(tt.tmpl, func(t *testing.T) {
+ fixture := testutil.NewFixture(t, tt.tmpl)
+ cmd := exec.Command(binaryPath)
+ cmd.Stdin = fixture.AsFile()
+ output, err := cmd.CombinedOutput()
+ if (err != nil) != tt.wantErr {
+ t.Fatalf("%s\nexpected (err != nil) to be %v, but got %v. err: %v", output, tt.wantErr, err != nil, err)
+ }
+
+ golden := testutil.NewGoldenFile(t, tt.golden)
+ actual := string(output)
+ if *update {
+ golden.Write(actual)
+ }
+
+ expected := golden.Load()
+
+ if !reflect.DeepEqual(actual, expected) {
+ t.Fatalf("diff: %v", testutil.Diff(expected, actual))
+ }
+ })
+ }
+}
diff --git a/loop.tmpl b/loop.tmpl
new file mode 100644
index 0000000..7486f51
--- /dev/null
+++ b/loop.tmpl
@@ -0,0 +1 @@
+[{{ range $index := Loop 5 }}"{{ Int }}"{{if lt $index 4}},{{end}}{{ end }}]
diff --git a/pkg/fakedata/template.go b/pkg/fakedata/template.go
index c11c3c3..15d2ce6 100644
--- a/pkg/fakedata/template.go
+++ b/pkg/fakedata/template.go
@@ -37,7 +37,12 @@ func (tf templateFactory) getFunctions() template.FuncMap {
}
}
- return make([]int, n)
+ times := make([]int, n)
+ for i := 0; i < n; i++ {
+ times[i] = i
+ }
+
+ return times
},
"Odd": func(i int) bool { return i%2 != 0 },
"Even": func(i int) bool { return i%2 == 0 },
diff --git a/testutil/fixtures/loop-with-index.tmpl b/testutil/fixtures/loop-with-index.tmpl
new file mode 100644
index 0000000..32127a5
--- /dev/null
+++ b/testutil/fixtures/loop-with-index.tmpl
@@ -0,0 +1 @@
+{{range $i := Loop 5}}{{$i}}{{end}}
diff --git a/testutil/golden/loop-with-index.golden b/testutil/golden/loop-with-index.golden
new file mode 100644
index 0000000..32e29c1
--- /dev/null
+++ b/testutil/golden/loop-with-index.golden
@@ -0,0 +1,10 @@
+01234
+01234
+01234
+01234
+01234
+01234
+01234
+01234
+01234
+01234