Skip to content

Commit 06be8cf

Browse files
committed
std - testingâ
1 parent c9620d5 commit 06be8cf

File tree

7 files changed

+348
-1
lines changed

7 files changed

+348
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,6 @@
151151
* [gorilla/sessions](https://darjun/github.io/2021/07/25/godailylib/gorilla/sessions)
152152
gorilla Web 开发包之 session 处理库
153153
* [goth](https://darjun/github.io/2021/07/26/godailylib/goth)
154-
第三方认证合集
154+
第三方认证合集
155+
* [testing](https://darjun/github.io/2021/08/03/godailylib/testing)
156+
标准库测试包

testing/fib/fib.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package fib
2+
3+
func Fib1(n int) int {
4+
if n <= 1 {
5+
return n
6+
}
7+
8+
return Fib1(n-1) + Fib1(n-2)
9+
}
10+
11+
func fibHelper(n int, m map[int]int) int {
12+
if n <= 1 {
13+
return n
14+
}
15+
16+
if v, ok := m[n]; ok {
17+
return v
18+
}
19+
20+
v := fibHelper(n-2, m) + fibHelper(n-1, m)
21+
m[n] = v
22+
return v
23+
}
24+
25+
func Fib2(n int) int {
26+
m := make(map[int]int)
27+
return fibHelper(n, m)
28+
}
29+
30+
func Fib3(n int) int {
31+
if n <= 1 {
32+
return n
33+
}
34+
35+
f1, f2 := 0, 1
36+
for i := 2; i <= n; i++ {
37+
f1, f2 = f2, f1+f2
38+
}
39+
40+
return f2
41+
}

testing/fib/fib_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package fib
2+
3+
import "testing"
4+
5+
func BenchmarkFib1(b *testing.B) {
6+
for i := 0; i < b.N; i++ {
7+
Fib1(20)
8+
}
9+
}
10+
11+
func BenchmarkFib2(b *testing.B) {
12+
for i := 0; i < b.N; i++ {
13+
Fib2(20)
14+
}
15+
}
16+
17+
func BenchmarkFib3(b *testing.B) {
18+
for i := 0; i < b.N; i++ {
19+
Fib3(20)
20+
}
21+
}

testing/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/darjun/go-daily-lib/testing
2+
3+
go 1.16

testing/roman/roman.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package roman
2+
3+
import (
4+
"bytes"
5+
"errors"
6+
"regexp"
7+
)
8+
9+
type romanNumPair struct {
10+
Roman string
11+
Num int
12+
}
13+
14+
var (
15+
romanNumParis []romanNumPair
16+
romanRegex *regexp.Regexp
17+
)
18+
19+
var (
20+
ErrOutOfRange = errors.New("out of range")
21+
ErrInvalidRoman = errors.New("invalid roman")
22+
)
23+
24+
func init() {
25+
romanNumParis = []romanNumPair{
26+
{"M", 1000},
27+
{"CM", 900},
28+
{"D", 500},
29+
{"CD", 400},
30+
{"C", 100},
31+
{"XC", 90},
32+
{"L", 50},
33+
{"XL", 40},
34+
{"X", 10},
35+
{"IX", 9},
36+
{"V", 5},
37+
{"IV", 4},
38+
{"I", 1},
39+
}
40+
41+
romanRegex = regexp.MustCompile(`^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$`)
42+
}
43+
44+
func ToRoman(n int) (string, error) {
45+
if n <= 0 || n >= 4000 {
46+
return "", ErrOutOfRange
47+
}
48+
var buf bytes.Buffer
49+
for _, pair := range romanNumParis {
50+
for n >= pair.Num {
51+
buf.WriteString(pair.Roman)
52+
n -= pair.Num
53+
}
54+
}
55+
56+
return buf.String(), nil
57+
}
58+
59+
func FromRoman(roman string) (int, error) {
60+
if !romanRegex.MatchString(roman) {
61+
return 0, ErrInvalidRoman
62+
}
63+
64+
var result int
65+
var index int
66+
for _, pair := range romanNumParis {
67+
for roman[index:index+len(pair.Roman)] == pair.Roman {
68+
result += pair.Num
69+
index += len(pair.Roman)
70+
}
71+
}
72+
73+
return result, nil
74+
}

testing/roman/roman_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package roman
2+
3+
import "testing"
4+
5+
func TestToRoman(t *testing.T) {
6+
testCases := []struct {
7+
num int
8+
expect string
9+
err error
10+
}{
11+
{0, "", ErrOutOfRange},
12+
{1, "I", nil},
13+
{2, "II", nil},
14+
{3, "III", nil},
15+
{4, "IV", nil},
16+
{5, "V", nil},
17+
{6, "VI", nil},
18+
{7, "VII", nil},
19+
{8, "VIII", nil},
20+
{9, "IX", nil},
21+
{10, "X", nil},
22+
{50, "L", nil},
23+
{100, "C", nil},
24+
{500, "D", nil},
25+
{1000, "M", nil},
26+
{31, "XXXI", nil},
27+
{148, "CXLVIII", nil},
28+
{294, "CCXCIV", nil},
29+
{312, "CCCXII", nil},
30+
{421, "CDXXI", nil},
31+
{528, "DXXVIII", nil},
32+
{621, "DCXXI", nil},
33+
{782, "DCCLXXXII", nil},
34+
{870, "DCCCLXX", nil},
35+
{941, "CMXLI", nil},
36+
{1043, "MXLIII", nil},
37+
{1110, "MCX", nil},
38+
{1226, "MCCXXVI", nil},
39+
{1301, "MCCCI", nil},
40+
{1485, "MCDLXXXV", nil},
41+
{1509, "MDIX", nil},
42+
{1607, "MDCVII", nil},
43+
{1754, "MDCCLIV", nil},
44+
{1832, "MDCCCXXXII", nil},
45+
{1993, "MCMXCIII", nil},
46+
{2074, "MMLXXIV", nil},
47+
{2152, "MMCLII", nil},
48+
{2212, "MMCCXII", nil},
49+
{2343, "MMCCCXLIII", nil},
50+
{2499, "MMCDXCIX", nil},
51+
{2574, "MMDLXXIV", nil},
52+
{2646, "MMDCXLVI", nil},
53+
{2723, "MMDCCXXIII", nil},
54+
{2892, "MMDCCCXCII", nil},
55+
{2975, "MMCMLXXV", nil},
56+
{3051, "MMMLI", nil},
57+
{3185, "MMMCLXXXV", nil},
58+
{3250, "MMMCCL", nil},
59+
{3313, "MMMCCCXIII", nil},
60+
{3408, "MMMCDVIII", nil},
61+
{3501, "MMMDI", nil},
62+
{3610, "MMMDCX", nil},
63+
{3743, "MMMDCCXLIII", nil},
64+
{3844, "MMMDCCCXLIV", nil},
65+
{3888, "MMMDCCCLXXXVIII", nil},
66+
{3940, "MMMCMXL", nil},
67+
{3999, "MMMCMXCIX", nil},
68+
{4000, "", ErrOutOfRange},
69+
}
70+
71+
for _, testCase := range testCases {
72+
got, err := ToRoman(testCase.num)
73+
if got != testCase.expect {
74+
t.Errorf("ToRoman(%d) expect:%s got:%s", testCase.num, testCase.expect, got)
75+
}
76+
77+
if err != testCase.err {
78+
t.Errorf("ToRoman(%d) expect error:%v got:%v", testCase.num, testCase.err, err)
79+
}
80+
}
81+
}

testing/roman_test/roman_test.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package roman_test
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"os"
7+
"testing"
8+
9+
"github.com/darjun/go-daily-lib/testing/roman"
10+
)
11+
12+
type toRomanCase struct {
13+
num int
14+
expect string
15+
err error
16+
}
17+
18+
var (
19+
toRomanInvalidCases []toRomanCase
20+
toRomanSingleCases []toRomanCase
21+
toRomanNormalCases []toRomanCase
22+
)
23+
24+
func init() {
25+
toRomanInvalidCases = []toRomanCase{
26+
{0, "", roman.ErrOutOfRange},
27+
{4000, "", roman.ErrOutOfRange},
28+
}
29+
30+
toRomanSingleCases = []toRomanCase{
31+
{1, "I", nil},
32+
{5, "V", nil},
33+
// ...
34+
}
35+
36+
toRomanNormalCases = []toRomanCase{
37+
{2, "II", nil},
38+
{3, "III", nil},
39+
{4, "IV", nil},
40+
{6, "VI", nil},
41+
{7, "VII", nil},
42+
{8, "VIII", nil},
43+
{9, "IX", nil},
44+
{31, "XXXI", nil},
45+
{148, "CXLVIII", nil},
46+
{294, "CCXCIV", nil},
47+
{312, "CCCXII", nil},
48+
{421, "CDXXI", nil},
49+
{528, "DXXVIII", nil},
50+
{621, "DCXXI", nil},
51+
{782, "DCCLXXXII", nil},
52+
{870, "DCCCLXX", nil},
53+
{941, "CMXLI", nil},
54+
{1043, "MXLIII", nil},
55+
{1110, "MCX", nil},
56+
{1226, "MCCXXVI", nil},
57+
{1301, "MCCCI", nil},
58+
{1485, "MCDLXXXV", nil},
59+
{1509, "MDIX", nil},
60+
{1607, "MDCVII", nil},
61+
{1754, "MDCCLIV", nil},
62+
{1832, "MDCCCXXXII", nil},
63+
{1993, "MCMXCIII", nil},
64+
{2074, "MMLXXIV", nil},
65+
{2152, "MMCLII", nil},
66+
{2212, "MMCCXII", nil},
67+
{2343, "MMCCCXLIII", nil},
68+
{2499, "MMCDXCIX", nil},
69+
{2574, "MMDLXXIV", nil},
70+
{2646, "MMDCXLVI", nil},
71+
{2723, "MMDCCXXIII", nil},
72+
{2892, "MMDCCCXCII", nil},
73+
{2975, "MMCMLXXV", nil},
74+
{3051, "MMMLI", nil},
75+
{3185, "MMMCLXXXV", nil},
76+
{3250, "MMMCCL", nil},
77+
{3313, "MMMCCCXIII", nil},
78+
{3408, "MMMCDVIII", nil},
79+
{3501, "MMMDI", nil},
80+
{3610, "MMMDCX", nil},
81+
{3743, "MMMDCCXLIII", nil},
82+
{3844, "MMMDCCCXLIV", nil},
83+
{3888, "MMMDCCCLXXXVIII", nil},
84+
{3940, "MMMCMXL", nil},
85+
{3999, "MMMCMXCIX", nil},
86+
}
87+
}
88+
func testToRomanCases(cases []toRomanCase, t *testing.T) {
89+
for _, testCase := range cases {
90+
got, err := roman.ToRoman(testCase.num)
91+
if got != testCase.expect {
92+
t.Errorf("ToRoman(%d) expect:%s got:%s", testCase.num, testCase.expect, got)
93+
}
94+
95+
if err != testCase.err {
96+
t.Errorf("ToRoman(%d) expect error:%v got:%v", testCase.num, testCase.err, err)
97+
}
98+
}
99+
}
100+
101+
func testToRomanInvalid(t *testing.T) {
102+
testToRomanCases(toRomanInvalidCases, t)
103+
}
104+
105+
func testToRomanSingle(t *testing.T) {
106+
testToRomanCases(toRomanSingleCases, t)
107+
}
108+
109+
func testToRomanNormal(t *testing.T) {
110+
testToRomanCases(toRomanNormalCases, t)
111+
}
112+
113+
func TestToRoman(t *testing.T) {
114+
t.Run("Invalid", testToRomanInvalid)
115+
t.Run("Single", testToRomanSingle)
116+
t.Run("Normal", testToRomanNormal)
117+
}
118+
119+
func TestMain(m *testing.M) {
120+
flag.Parse()
121+
flag.VisitAll(func(f *flag.Flag) {
122+
fmt.Printf("name:%s usage:%s value:%v\n", f.Name, f.Usage, f.Value)
123+
})
124+
os.Exit(m.Run())
125+
}

0 commit comments

Comments
 (0)