Skip to content

Commit e003dda

Browse files
Merge branch 'master' of https://github.com/ardanlabs/gotraining
2 parents 2fae388 + 9e53b01 commit e003dda

File tree

12 files changed

+283
-0
lines changed

12 files changed

+283
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ July(10-12) Chicago, IL Enova Corporate Adv G
187187
July(24-26) St. Louis, MO Centene Corporate Go (3 day)
188188
September(11-13) Santa Monica, CA ZipRecruiter Corporate Go (3 day)
189189
October(09-11) San Jose, CA Oracle Corporate Adv Go (3 day)
190+
October(16-18) Torrance, CA Dollar Shave Club Corporate Go (3 day)
190191
October(23-25) St. Louis, MO Centene Corporate Go (3 day)
191192
November(07-09) Portland, OR New Relic Corporate Go (3 day)
192193
```

topics/go/testing/strings/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## Strings Testing
2+
3+
This package is an exercise intended to introduce the most commonly used testing and benchmarking tools.
4+
5+
## Package Review
6+
7+
[Basic Tests](example1/)
8+
[Table Driven Tests](example2/)
9+
[Subtests](example3/)
10+
[Benchmarks](example4/)
11+
12+
_Look at the [benchmarks](../benchmarks/README.md) section to learn more about measuring performance._
13+
14+
_Look at the profiling topic to learn more about using benchmarks to [profile](../../profiling/README.md) code._
15+
16+
## Links
17+
18+
[Table Driven Tests / Dave Cheney](https://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go).
19+
20+
___
21+
All material is licensed under the [Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0).
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// All material is licensed under the Apache License Version 2.0, January 2004
2+
// http://www.apache.org/licenses/LICENSE-2.0
3+
4+
// Package strings provides some useful string manipulation functions.
5+
package strings
6+
7+
// Reverse gives the reversed form of s.
8+
//
9+
// This is the initial implementation.
10+
// It passes our test so it must be good! :)
11+
func Reverse(s string) string {
12+
return "bocaj"
13+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// All material is licensed under the Apache License Version 2.0, January 2004
2+
// http://www.apache.org/licenses/LICENSE-2.0
3+
4+
// Go + testing = ❤!
5+
//
6+
// This is our first iteration of the test. It only tests a single
7+
// input/output combination. Run this with:
8+
//
9+
// go test
10+
package strings
11+
12+
import "testing"
13+
14+
func TestReverse(t *testing.T) {
15+
in := "jacob"
16+
want := "bocaj"
17+
got := Reverse(in)
18+
19+
if got != want {
20+
t.Errorf("Reverse(%q) = %q, want %q", in, got, want)
21+
}
22+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// All material is licensed under the Apache License Version 2.0, January 2004
2+
// http://www.apache.org/licenses/LICENSE-2.0
3+
4+
// Package strings provides some useful string manipulation functions.
5+
package strings
6+
7+
// Reverse gives the reversed form of s.
8+
//
9+
// This is the first real implementation.
10+
// It is not very efficient and it will fail on multibyte input.
11+
func Reverse(s string) string {
12+
var r string
13+
14+
for i := len(s) - 1; i >= 0; i-- {
15+
r = r + string(s[i])
16+
}
17+
18+
return r
19+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// All material is licensed under the Apache License Version 2.0, January 2004
2+
// http://www.apache.org/licenses/LICENSE-2.0
3+
4+
// Go + testing = ❤!
5+
//
6+
// This is our second test iteration. We define a type for a test scenario as
7+
// well as a "table" of test inputs. We loop over that and run each test. This
8+
// is commonly called a "Table Driven Test".
9+
package strings
10+
11+
import "testing"
12+
13+
// reverseTest defines a single scenario for testing the Reverse function.
14+
type reverseTest struct {
15+
in string
16+
want string
17+
}
18+
19+
func TestReverse(t *testing.T) {
20+
21+
// tests is a "table" of test scenarios.
22+
tests := []reverseTest{
23+
{"jacob", "bocaj"},
24+
{"john", "nhoj"},
25+
}
26+
27+
// loop through the table and run each test.
28+
for _, test := range tests {
29+
got := Reverse(test.in)
30+
if got != test.want {
31+
t.Errorf("Reverse(%q) = %q, want %q", test.in, got, test.want)
32+
}
33+
}
34+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// All material is licensed under the Apache License Version 2.0, January 2004
2+
// http://www.apache.org/licenses/LICENSE-2.0
3+
4+
// Package strings provides some useful string manipulation functions.
5+
package strings
6+
7+
// Reverse gives the reversed form of s.
8+
//
9+
// This is the first correct implementation. It may not behave how you want for
10+
// things like unicode combining characters. If you can break it let me know :)
11+
//
12+
// It is still not very efficient but maybe it's good enough?
13+
func Reverse(s string) string {
14+
in := []rune(s)
15+
var r string
16+
17+
for i := len(in) - 1; i >= 0; i-- {
18+
r = r + string(in[i])
19+
}
20+
21+
return r
22+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// All material is licensed under the Apache License Version 2.0, January 2004
2+
// http://www.apache.org/licenses/LICENSE-2.0
3+
4+
// Go + testing = ❤!
5+
//
6+
// This is our third test iteration. We added more scenarios but one is
7+
// failing. We name each of our scenarios so we can identify the failing
8+
// scenario. We also launch them in subtests so we can run just the failing
9+
// scenario on demand. Run with -v to see each subtest in action. To limit
10+
// execution use -run:
11+
//
12+
// go test -v
13+
// go test -v -run TestReverse/multibyte
14+
package strings
15+
16+
import "testing"
17+
18+
// reverseTest defines a single scenario for testing the Reverse function.
19+
type reverseTest struct {
20+
name string
21+
in string
22+
want string
23+
}
24+
25+
func TestReverse(t *testing.T) {
26+
27+
// tests is a "table" of test scenarios.
28+
tests := []reverseTest{
29+
{"odd", "jacob", "bocaj"},
30+
{"even", "john", "nhoj"},
31+
{"multibyte", "I ❤ NY", "YN ❤ I"},
32+
{"empty", "", ""},
33+
}
34+
35+
// loop through the table and run each test.
36+
for _, test := range tests {
37+
38+
// Encapsulate the test behavior in a closure.
39+
fn := func(t *testing.T) {
40+
got := Reverse(test.in)
41+
if got != test.want {
42+
t.Errorf("Reverse(%q) = %q, want %q", test.in, got, test.want)
43+
}
44+
}
45+
46+
// Run the test closure as a subtest
47+
t.Run(test.name, fn)
48+
}
49+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// All material is licensed under the Apache License Version 2.0, January 2004
2+
// http://www.apache.org/licenses/LICENSE-2.0
3+
4+
// Package strings provides some useful string manipulation functions.
5+
package strings
6+
7+
// Reverse gives the reversed form of s.
8+
//
9+
// This implementation attempts to improve performance by removing unnecessary
10+
// string conversions. Further improvements could be made by:
11+
//
12+
// 1. Preallocating enough capacity in r.
13+
// 2. Remove r and sort the input in place.
14+
// 3. Something much more complicated.
15+
func Reverse(s string) string {
16+
in := []rune(s)
17+
var r []rune
18+
19+
for i := len(in) - 1; i >= 0; i-- {
20+
r = append(r, in[i])
21+
}
22+
23+
return string(r)
24+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// All material is licensed under the Apache License Version 2.0, January 2004
2+
// http://www.apache.org/licenses/LICENSE-2.0
3+
4+
// Go + testing = ❤!
5+
//
6+
// In this iteration we haven't really changed the test but we have added a
7+
// benchmark. This is how we can measure the performance of our function. To
8+
// run benchmarks run these commands:
9+
//
10+
// go test -bench .
11+
// go test -bench . -benchmem
12+
// go test -bench . -benchmem -benchtime 5s
13+
package strings
14+
15+
import "testing"
16+
17+
// reverseTest defines a single scenario for testing the Reverse function.
18+
type reverseTest struct {
19+
name string
20+
in string
21+
want string
22+
}
23+
24+
func TestReverse(t *testing.T) {
25+
26+
// tests is a "table" of test scenarios.
27+
tests := []reverseTest{
28+
{"odd", "jacob", "bocaj"},
29+
{"even", "john", "nhoj"},
30+
{"multibyte", "I ❤ NY", "YN ❤ I"},
31+
{"empty", "", ""},
32+
{"alphabet", "abcdefghijklmnopqrstuvwxyz", "zyxwvutsrqponmlkjihgfedcba"},
33+
}
34+
35+
// loop through the table and run each test.
36+
for _, test := range tests {
37+
38+
// Encapsulate the test behavior in a closure.
39+
fn := func(t *testing.T) {
40+
got := Reverse(test.in)
41+
if got != test.want {
42+
t.Errorf("Reverse(%q) = %q, want %q", test.in, got, test.want)
43+
}
44+
}
45+
46+
// Run the test closure as a subtest
47+
t.Run(test.name, fn)
48+
}
49+
}
50+
51+
func BenchmarkReverse(b *testing.B) {
52+
for i := 0; i < b.N; i++ {
53+
Reverse("abcdefghijklmnopqrstuvwxyz")
54+
}
55+
}

topics/go/testing/strings/reverse.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// All material is licensed under the Apache License Version 2.0, January 2004
2+
// http://www.apache.org/licenses/LICENSE-2.0
3+
4+
// Package strings provides some useful string manipulation functions.
5+
package strings
6+
7+
// Reverse gives the reversed form of s.
8+
func Reverse(s string) string {
9+
return ""
10+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// All material is licensed under the Apache License Version 2.0, January 2004
2+
// http://www.apache.org/licenses/LICENSE-2.0
3+
4+
// Go + testing = ❤!
5+
//
6+
// This is the basic structure for writing tests. Follow along with the
7+
// instructor or look ahead to "example1" to see the first iteration.
8+
package strings
9+
10+
import "testing"
11+
12+
func TestReverse(t *testing.T) {
13+
}

0 commit comments

Comments
 (0)