Skip to content

Commit a2ad2a2

Browse files
committed
docs: refactor tests, Property -> Field, Add Last
1 parent 4964789 commit a2ad2a2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+613
-522
lines changed

Diff for: README.md

+62-64
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
\_/__/
1010
```
1111

12-
# Underscore.go [![GoDoc](https://godoc.org/github.com/ahl5esoft/golang-underscore?status.svg)](https://godoc.org/github.com/ahl5esoft/golang-underscore) [![Go Report Card](https://goreportcard.com/badge/github.com/ahl5esoft/golang-underscore)](https://goreportcard.com/report/github.com/ahl5esoft/golang-underscore) ![Version](https://img.shields.io/badge/version-2.1.1-green.svg)
12+
# Underscore.go [![GoDoc](https://godoc.org/github.com/ahl5esoft/golang-underscore?status.svg)](https://godoc.org/github.com/ahl5esoft/golang-underscore) [![Go Report Card](https://goreportcard.com/badge/github.com/ahl5esoft/golang-underscore)](https://goreportcard.com/report/github.com/ahl5esoft/golang-underscore) ![Version](https://img.shields.io/badge/version-2.1.2-green.svg)
1313
like <a href="http://underscorejs.org/">underscore.js</a> and C# LINQ, but for Go
1414

1515
## Installation
@@ -31,6 +31,7 @@ like <a href="http://underscorejs.org/">underscore.js</a> and C# LINQ, but for G
3131
* [`Count`](#count)
3232
* [`Distinct`](#distinct), [`DistinctBy`](#distinctBy)
3333
* [`Each`](#each)
34+
* [`Field`](#field), [`FieldValue`](#fieldValue)
3435
* [`Filter`](#where), [`FilterBy`](#whereBy)
3536
* [`Find`](#find), [`FindBy`](#findBy)
3637
* [`FindIndex`](#findIndex), [`FindIndexBy`](#findIndexBy)
@@ -45,7 +46,6 @@ like <a href="http://underscorejs.org/">underscore.js</a> and C# LINQ, but for G
4546
* [`MapMany`](#selectMany), [`MapManyBy`](#selectManyBy)
4647
* [`Object`](#object)
4748
* [`Order`](#order), [`OrderBy`](#orderBy)
48-
* [`Property`](#property), [`PropertyRV`](#propertyRV)
4949
* [`Range`](#range)
5050
* [`Reduce`](#aggregate)
5151
* [`Reject`](#reject), [`RejectBy`](#rejectBy)
@@ -294,6 +294,58 @@ Chain(arr).Each(func(r testModel, i int) {
294294
})
295295
```
296296

297+
<a name="field" />
298+
299+
### Field(name)
300+
301+
__Arguments__
302+
303+
* `name` - field name
304+
305+
__Return__
306+
307+
* func(interface{}) interface{}
308+
309+
__Examples__
310+
311+
```go
312+
item := testModel{ 1, "one" }
313+
314+
getAge := Field("age")
315+
_, err := getAge(item)
316+
// err != nil
317+
318+
getName := Field("name")
319+
name, err := getName(item)
320+
// name = "one"
321+
```
322+
323+
<a name="fieldValue" />
324+
325+
### FieldValue(name)
326+
327+
__Arguments__
328+
329+
* `name` - field name
330+
331+
__Return__
332+
333+
* func(interface{}) reflect.Value
334+
335+
__Examples__
336+
337+
```go
338+
item := testModel{ 1, "one" }
339+
340+
getAgeValue := FieldValue("age")
341+
res := getAgeValue(item)
342+
// res != reflect.Value(nil)
343+
344+
getNameValue := FieldValue("name")
345+
nameValue, err := getNameValue(item)
346+
// nameValue = reflect.ValueOf("one")
347+
```
348+
297349
<a name="find" />
298350

299351
### Find(predicate) IEnumerable
@@ -595,19 +647,17 @@ __Examples__
595647
arr := []int{1, 2, 3}
596648
var res int
597649
chain(arr).Last().Value(&res)
598-
// or
599-
res := Last(arr).(int)
600650
// res = 3
601651

602-
dict := map[string]string{
603-
"a": "aa",
604-
"b": "bb",
652+
var res []int
653+
src := [][]int{
654+
{1, 2, 3, 4},
655+
{5, 6},
605656
}
606-
var str string
607-
Chain(dict).Last().Value(&str)
608-
// or
609-
str := Last(dict).(string)
610-
// res = "aa" or "bb"
657+
Chain(src).Last().Map(func(r, _ int) int {
658+
return r + 5
659+
}).Value(&res)
660+
// res = [10, 11]
611661
```
612662

613663
<a name="object" />
@@ -679,58 +729,6 @@ __Same__
679729

680730
* `SortBy`
681731

682-
<a name="property" />
683-
684-
### Property(name)
685-
686-
__Arguments__
687-
688-
* `name` - property name
689-
690-
__Return__
691-
692-
* func(interface{}) (interface{}, error)
693-
694-
__Examples__
695-
696-
```go
697-
item := testModel{ 1, "one" }
698-
699-
getAge := Property("age")
700-
_, err := getAge(item)
701-
// err != nil
702-
703-
getName := Property("name")
704-
name, err := getName(item)
705-
// name = "one"
706-
```
707-
708-
<a name="propertyRV" />
709-
710-
### Property(name)
711-
712-
__Arguments__
713-
714-
* `name` - property name
715-
716-
__Return__
717-
718-
* func(interface{}) (reflect.Value, error)
719-
720-
__Examples__
721-
722-
```go
723-
item := testModel{ 1, "one" }
724-
725-
getAgeRV := PropertyRV("age")
726-
_, err := getAgeRV(item)
727-
// err != nil
728-
729-
getNameRV := PropertyRV("name")
730-
nameRV, err := getNameRV(item)
731-
// nameRV = reflect.ValueOf("one")
732-
```
733-
734732
<a name="range" />
735733

736734
### Range(start, stop, step) IEnumerable

Diff for: distinct.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func (m enumerable) Distinct(selector interface{}) IEnumerable {
2121
for ok = iterator.MoveNext(); ok; ok = iterator.MoveNext() {
2222
valueValue = iterator.GetValue()
2323
keyValue = iterator.GetKey()
24-
v := getFuncReturnRV(selectValue, iterator).Interface()
24+
v := getReturnValue(selectValue, iterator).Interface()
2525
if _, has := set[v]; !has {
2626
set[v] = true
2727
return
@@ -35,7 +35,7 @@ func (m enumerable) Distinct(selector interface{}) IEnumerable {
3535
}
3636

3737
func (m enumerable) DistinctBy(fieldName string) IEnumerable {
38-
getter := PropertyRV(fieldName)
38+
getter := FieldValue(fieldName)
3939
return m.Distinct(func(value, _ interface{}) facade {
4040
return facade{
4141
getter(value),

Diff for: each_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package underscore
33
import (
44
"testing"
55

6-
"github.com/go-playground/assert/v2"
6+
"github.com/stretchr/testify/assert"
77
)
88

99
func Test_Each(t *testing.T) {

Diff for: enumerator.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func (m enumerator) GetKey() reflect.Value {
1616
}
1717

1818
func (m enumerator) GetValue() reflect.Value {
19-
return getRealRV(m.value)
19+
return getRealValue(m.value)
2020
}
2121

2222
func (m *enumerator) MoveNext() (ok bool) {

Diff for: property.go renamed to field.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@ import (
55
"strings"
66
)
77

8-
// GetProeprtyRVFunc is get property reflect.Value func
9-
type GetProeprtyRVFunc func(interface{}) reflect.Value
8+
// GetFieldValueFunc is get field reflect.Value func
9+
type GetFieldValueFunc func(interface{}) reflect.Value
1010

11-
// Property is 获取属性函数
12-
func Property(name string) func(interface{}) interface{} {
13-
fn := PropertyRV(name)
11+
// Field is 获取字段函数
12+
func Field(name string) func(interface{}) interface{} {
13+
fn := FieldValue(name)
1414
return func(item interface{}) interface{} {
1515
return fn(item).Interface()
1616
}
1717
}
1818

19-
// PropertyRV is 获取reflect.Value
20-
func PropertyRV(name string) GetProeprtyRVFunc {
21-
var getter GetProeprtyRVFunc
19+
// FieldValue is 获取reflect.Value
20+
func FieldValue(name string) GetFieldValueFunc {
21+
var getter GetFieldValueFunc
2222
getter = func(item interface{}) reflect.Value {
23-
itemRV := getRealRV(item)
23+
itemRV := getRealValue(item)
2424
itemRT := itemRV.Type()
2525
for i := 0; i < itemRT.NumField(); i++ {
2626
field := itemRT.Field(i)

Diff for: field_test.go

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package underscore
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func Benchmark_Field(b *testing.B) {
10+
for n := 0; n < b.N; n++ {
11+
Field("id")(testModel{ID: 1, Name: "one"})
12+
}
13+
}
14+
15+
func Benchmark_FieldValue(b *testing.B) {
16+
for n := 0; n < b.N; n++ {
17+
FieldValue("id")(testModel{ID: 1, Name: "one"})
18+
}
19+
}
20+
21+
func Benchmark_FieldValue_InvalidName(b *testing.B) {
22+
for n := 0; n < b.N; n++ {
23+
FieldValue("$$")(testModel{ID: 1, Name: "one"})
24+
}
25+
}
26+
27+
func Benchmark_FieldValue_Nested(b *testing.B) {
28+
for n := 0; n < b.N; n++ {
29+
FieldValue("id")(testNestedModel{
30+
testModel: testModel{
31+
ID: 11,
32+
},
33+
})
34+
}
35+
}
36+
37+
func Benchmark_FieldValue_Ptr(b *testing.B) {
38+
for n := 0; n < b.N; n++ {
39+
FieldValue("id")(&testModel{ID: 1, Name: "ptr"})
40+
}
41+
}
42+
43+
func Test_Field(t *testing.T) {
44+
item := testModel{ID: 1, Name: "one"}
45+
getName := Field("name")
46+
name := getName(item)
47+
assert.Equal(
48+
t,
49+
name,
50+
item.Name,
51+
)
52+
}
53+
54+
func Test_Field_Nested(t *testing.T) {
55+
item := testNestedModel{
56+
testModel: testModel{
57+
ID: 11,
58+
},
59+
}
60+
id, ok := Field("id")(item).(int)
61+
assert.True(t, ok)
62+
assert.Equal(t, id, 11)
63+
}
64+
65+
func Test_Field_Ptr(t *testing.T) {
66+
item := &testModel{ID: 1, Name: "ptr"}
67+
nameGetter := Field("name")
68+
name := nameGetter(item)
69+
assert.Equal(t, name, item.Name)
70+
}
71+
72+
func Test_FieldValue(t *testing.T) {
73+
item := testModel{ID: 1, Name: "one"}
74+
75+
value := FieldValue("$$")(item)
76+
assert.Equal(t, value, nilValue)
77+
78+
getNameValue := FieldValue("name")
79+
nameValue := getNameValue(item)
80+
assert.Equal(
81+
t,
82+
nameValue.String(),
83+
item.Name,
84+
)
85+
}

Diff for: filter_test.go

+19-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package underscore
22

3-
import "testing"
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
48

59
func Test_Filter(t *testing.T) {
610
src := []testModel{
@@ -9,13 +13,15 @@ func Test_Filter(t *testing.T) {
913
{ID: 3, Name: "three"},
1014
{ID: 4, Name: "three"},
1115
}
12-
dst := make([]testModel, 0)
16+
var res []testModel
1317
Chain(src).Filter(func(r testModel, _ int) bool {
1418
return r.ID%2 == 0
15-
}).Value(&dst)
16-
if !(len(dst) == 2 && dst[0] == src[1] && dst[1] == src[3]) {
17-
t.Error(dst)
18-
}
19+
}).Value(&res)
20+
assert.EqualValues(
21+
t,
22+
res,
23+
[]testModel{src[1], src[3]},
24+
)
1925
}
2026

2127
func Test_FilterBy(t *testing.T) {
@@ -25,11 +31,13 @@ func Test_FilterBy(t *testing.T) {
2531
{ID: 3, Name: "three"},
2632
{ID: 4, Name: "three"},
2733
}
28-
dst := make([]testModel, 0)
34+
var res []testModel
2935
Chain(src).FilterBy(map[string]interface{}{
3036
"Name": "one",
31-
}).Value(&dst)
32-
if !(len(dst) == 2 && dst[0] == src[0] && dst[1] == src[1]) {
33-
t.Error("wrong result")
34-
}
37+
}).Value(&res)
38+
assert.EqualValues(
39+
t,
40+
res,
41+
[]testModel{src[0], src[1]},
42+
)
3543
}

0 commit comments

Comments
 (0)