From 62a3f1693d1eef9ac5df50bd3948d0b8aa3d7eef Mon Sep 17 00:00:00 2001 From: jroam Date: Mon, 8 Jul 2019 23:25:47 +0800 Subject: [PATCH] add some garray tests --- .../garray/garray_z_unit_basic_test.go | 21 +++- .../garray/garray_z_unit_interface_test.go | 113 +++++++++++++++++ .../garray/garray_z_unit_string_test.go | 119 +++++++++++++++++- 3 files changed, 246 insertions(+), 7 deletions(-) diff --git a/g/container/garray/garray_z_unit_basic_test.go b/g/container/garray/garray_z_unit_basic_test.go index a387bd3c0..93a3882d5 100644 --- a/g/container/garray/garray_z_unit_basic_test.go +++ b/g/container/garray/garray_z_unit_basic_test.go @@ -44,11 +44,15 @@ func Test_SortedIntArray2(t *testing.T) { func Test_SortedStringArray1(t *testing.T) { expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} - array := garray.NewSortedStringArray() + array1 := garray.NewSortedStringArray() + array2 := garray.NewSortedStringArray(true) for i := 10; i > -1; i-- { - array.Add(gconv.String(i)) + array1.Add(gconv.String(i)) + array2.Add(gconv.String(i)) } - gtest.Assert(array.Slice(), expect) + gtest.Assert(array1.Slice(), expect) + gtest.Assert(array2.Slice(), expect) + } func Test_SortedStringArray2(t *testing.T) { @@ -58,6 +62,8 @@ func Test_SortedStringArray2(t *testing.T) { array.Add(gconv.String(i)) } gtest.Assert(array.Slice(), expect) + array.Add() + gtest.Assert(array.Slice(), expect) } func Test_SortedArray1(t *testing.T) { @@ -73,13 +79,18 @@ func Test_SortedArray1(t *testing.T) { func Test_SortedArray2(t *testing.T) { expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} - array := garray.NewSortedArray(func(v1, v2 interface{}) int { + func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) - }) + } + array := garray.NewSortedArray(func1) + array2 := garray.NewSortedArray(func1, true) for i := 0; i <= 10; i++ { array.Add(gconv.String(i)) + array2.Add(gconv.String(i)) } gtest.Assert(array.Slice(), expect) + gtest.Assert(array.Add().Slice(), expect) + gtest.Assert(array2.Slice(), expect) } func TestNewFromCopy(t *testing.T) { diff --git a/g/container/garray/garray_z_unit_interface_test.go b/g/container/garray/garray_z_unit_interface_test.go index 90ed36d6b..971549a53 100644 --- a/g/container/garray/garray_z_unit_interface_test.go +++ b/g/container/garray/garray_z_unit_interface_test.go @@ -14,6 +14,7 @@ import ( "github.com/gogf/gf/g/util/gconv" "strings" "testing" + "time" ) func Test_Array_Basic(t *testing.T) { @@ -496,6 +497,7 @@ func TestSortedArray_Range(t *testing.T) { return strings.Compare(gconv.String(v1), gconv.String(v2)) } array1 := garray.NewSortedArrayFrom(a1, func1) + array2 := garray.NewSortedArrayFrom(a1, func1, true) i1 := array1.Range(2, 5) gtest.Assert(i1, []interface{}{"c", "d", "e"}) gtest.Assert(array1.Len(), 6) @@ -509,6 +511,8 @@ func TestSortedArray_Range(t *testing.T) { gtest.Assert(len(i2), 2) gtest.Assert(i2, []interface{}{"e", "f"}) + gtest.Assert(array2.Range(1, 3), []interface{}{"b", "c"}) + }) } @@ -587,6 +591,7 @@ func TestSortedArray_SubSlice(t *testing.T) { return strings.Compare(gconv.String(v1), gconv.String(v2)) } array1 := garray.NewSortedArrayFrom(a1, func1) + array2 := garray.NewSortedArrayFrom(a1, func1, true) i1 := array1.SubSlice(2, 3) gtest.Assert(len(i1), 3) gtest.Assert(i1, []interface{}{"c", "d", "e"}) @@ -598,6 +603,13 @@ func TestSortedArray_SubSlice(t *testing.T) { i1 = array1.SubSlice(7, 2) gtest.Assert(len(i1), 0) + s1 := array1.SubSlice(1, -2) + gtest.Assert(s1, nil) + + s1 = array1.SubSlice(-9, 2) + gtest.Assert(s1, nil) + gtest.Assert(array2.SubSlice(1, 3), []interface{}{"b", "c", "d"}) + }) } @@ -676,3 +688,104 @@ func TestSortedArray_SetUnique(t *testing.T) { gtest.Assert(array1, []interface{}{"a", "c", "d"}) }) } + +func TestSortedArray_LockFunc(t *testing.T) { + gtest.Case(t, func() { + func1 := func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + } + s1 := []interface{}{"a", "b", "c", "d"} + a1 := garray.NewSortedArrayFrom(s1, func1) + + ch1 := make(chan int64, 3) + ch2 := make(chan int64, 3) + //go1 + go a1.LockFunc(func(n1 []interface{}) { //读写锁 + time.Sleep(2 * time.Second) //暂停2秒 + n1[2] = "g" + ch2 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }) + + //go2 + go func() { + time.Sleep(100 * time.Millisecond) //故意暂停0.01秒,等go1执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + <-ch2 //等待go1完成 + + // 防止ci抖动,以豪秒为单位 + gtest.AssertGT(t2-t1, 20) //go1加的读写互斥锁,所go2读的时候被阻塞。 + gtest.Assert(a1.Contains("g"), true) + }) +} + +func TestSortedArray_RLockFunc(t *testing.T) { + gtest.Case(t, func() { + func1 := func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + } + s1 := []interface{}{"a", "b", "c", "d"} + a1 := garray.NewSortedArrayFrom(s1, func1) + + ch1 := make(chan int64, 3) + ch2 := make(chan int64, 3) + //go1 + go a1.RLockFunc(func(n1 []interface{}) { //读写锁 + time.Sleep(2 * time.Second) //暂停2秒 + n1[2] = "g" + ch2 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }) + + //go2 + go func() { + time.Sleep(100 * time.Millisecond) //故意暂停0.01秒,等go1执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + <-ch2 //等待go1完成 + + // 防止ci抖动,以豪秒为单位 + gtest.AssertLT(t2-t1, 20) //go1加的读锁,所go2读的时候不会被阻塞。 + gtest.Assert(a1.Contains("g"), true) + }) +} + +func TestSortedArray_Merge(t *testing.T) { + gtest.Case(t, func() { + func1 := func(v1, v2 interface{}) int { + if gconv.Int(v1) < gconv.Int(v2) { + return 0 + } + return 1 + } + + s1 := []interface{}{"a", "b", "c", "d"} + s2 := []string{"e", "f"} + i1 := garray.NewIntArrayFrom([]int{1, 2, 3}) + i2 := garray.NewArrayFrom([]interface{}{3}) + s3 := garray.NewStringArrayFrom([]string{"g", "h"}) + s4 := garray.NewSortedArrayFrom([]interface{}{4, 5}, func1) + s5 := garray.NewSortedStringArrayFrom(s2) + s6 := garray.NewSortedIntArrayFrom([]int{1, 2, 3}) + + a1 := garray.NewSortedArrayFrom(s1, func1) + + gtest.Assert(a1.Merge(s2).Len(), 6) + gtest.Assert(a1.Merge(i1).Len(), 9) + gtest.Assert(a1.Merge(i2).Len(), 10) + gtest.Assert(a1.Merge(s3).Len(), 12) + gtest.Assert(a1.Merge(s4).Len(), 14) + gtest.Assert(a1.Merge(s5).Len(), 16) + gtest.Assert(a1.Merge(s6).Len(), 19) + + }) +} diff --git a/g/container/garray/garray_z_unit_string_test.go b/g/container/garray/garray_z_unit_string_test.go index 5c7f5b8fe..9f3547618 100644 --- a/g/container/garray/garray_z_unit_string_test.go +++ b/g/container/garray/garray_z_unit_string_test.go @@ -487,6 +487,7 @@ func TestSortedStringArray_Range(t *testing.T) { gtest.Case(t, func() { a1 := []string{"e", "a", "d", "c", "b", "f", "g"} array1 := garray.NewSortedStringArrayFrom(a1) + array2 := garray.NewSortedStringArrayFrom(a1, true) s1 := array1.Range(2, 4) gtest.Assert(len(s1), 2) gtest.Assert(s1, []string{"c", "d"}) @@ -498,6 +499,11 @@ func TestSortedStringArray_Range(t *testing.T) { s1 = array1.Range(4, 8) gtest.Assert(len(s1), 3) gtest.Assert(s1, []string{"e", "f", "g"}) + gtest.Assert(array1.Range(10, 2), nil) + + s2 := array2.Range(2, 4) + gtest.Assert(s2, []string{"c", "d"}) + }) } @@ -537,6 +543,7 @@ func TestSortedStringArray_SubSlice(t *testing.T) { gtest.Case(t, func() { a1 := []string{"e", "a", "d", "c", "b", "f", "g"} array1 := garray.NewSortedStringArrayFrom(a1) + array2 := garray.NewSortedStringArrayFrom(a1, true) s1 := array1.SubSlice(1, 3) gtest.Assert(len(s1), 3) gtest.Assert(s1, []string{"b", "c", "d"}) @@ -548,6 +555,17 @@ func TestSortedStringArray_SubSlice(t *testing.T) { s3 := array1.SubSlice(10, 2) gtest.Assert(len(s3), 0) + s3 = array1.SubSlice(-5, 2) + gtest.Assert(s3, []string{"c", "d"}) + + s3 = array1.SubSlice(-10, 2) + gtest.Assert(s3, nil) + + s3 = array1.SubSlice(1, -2) + gtest.Assert(s3, nil) + + gtest.Assert(array2.SubSlice(1, 3), []string{"b", "c", "d"}) + }) } @@ -612,6 +630,7 @@ func TestSortedStringArray_Chunk(t *testing.T) { gtest.Assert(len(array2), 3) gtest.Assert(len(array2[0]), 2) gtest.Assert(array2[1], []string{"c", "d"}) + gtest.Assert(array1.Chunk(0), nil) }) } @@ -645,11 +664,12 @@ func TestStringArray_RLockFunc(t *testing.T) { a1 := garray.NewStringArrayFrom(s1, true) ch1 := make(chan int64, 3) + ch2 := make(chan int64, 1) //go1 go a1.RLockFunc(func(n1 []string) { //读锁 time.Sleep(2 * time.Second) //暂停1秒 n1[2] = "g" - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + ch2 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) }) //go2 @@ -662,10 +682,105 @@ func TestStringArray_RLockFunc(t *testing.T) { t1 := <-ch1 t2 := <-ch1 - <-ch1 //等待go1完成 + <-ch2 //等待go1完成 // 防止ci抖动,以豪秒为单位 gtest.AssertLT(t2-t1, 20) //go1加的读锁,所go2读的时候,并没有阻塞。 gtest.Assert(a1.Contains("g"), true) }) } + +func TestSortedStringArray_LockFunc(t *testing.T) { + gtest.Case(t, func() { + s1 := []string{"a", "b", "c", "d"} + a1 := garray.NewSortedStringArrayFrom(s1) + + ch1 := make(chan int64, 3) + ch2 := make(chan int64, 3) + //go1 + go a1.LockFunc(func(n1 []string) { //读写锁 + time.Sleep(2 * time.Second) //暂停2秒 + n1[2] = "g" + ch2 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }) + + //go2 + go func() { + time.Sleep(100 * time.Millisecond) //故意暂停0.01秒,等go1执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + <-ch2 //等待go1完成 + + // 防止ci抖动,以豪秒为单位 + gtest.AssertGT(t2-t1, 20) //go1加的读写互斥锁,所go2读的时候被阻塞。 + gtest.Assert(a1.Contains("g"), true) + }) +} + +func TestSortedStringArray_RLockFunc(t *testing.T) { + gtest.Case(t, func() { + s1 := []string{"a", "b", "c", "d"} + a1 := garray.NewSortedStringArrayFrom(s1) + + ch1 := make(chan int64, 3) + ch2 := make(chan int64, 1) + //go1 + go a1.RLockFunc(func(n1 []string) { //读锁 + time.Sleep(2 * time.Second) //暂停1秒 + n1[2] = "g" + ch2 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }) + + //go2 + go func() { + time.Sleep(100 * time.Millisecond) //故意暂停0.01秒,等go1执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + <-ch2 //等待go1完成 + + // 防止ci抖动,以豪秒为单位 + gtest.AssertLT(t2-t1, 20) //go1加的读锁,所go2读的时候,并没有阻塞。 + gtest.Assert(a1.Contains("g"), true) + }) +} + +func TestSortedStringArray_Merge(t *testing.T) { + gtest.Case(t, func() { + func1 := func(v1, v2 interface{}) int { + if gconv.Int(v1) < gconv.Int(v2) { + return 0 + } + return 1 + } + + s1 := []string{"a", "b", "c", "d"} + s2 := []string{"e", "f"} + i1 := garray.NewIntArrayFrom([]int{1, 2, 3}) + i2 := garray.NewArrayFrom([]interface{}{3}) + s3 := garray.NewStringArrayFrom([]string{"g", "h"}) + s4 := garray.NewSortedArrayFrom([]interface{}{4, 5}, func1) + s5 := garray.NewSortedStringArrayFrom(s2) + s6 := garray.NewSortedIntArrayFrom([]int{1, 2, 3}) + + a1 := garray.NewSortedStringArrayFrom(s1) + + gtest.Assert(a1.Merge(s2).Len(), 6) + gtest.Assert(a1.Merge(i1).Len(), 9) + gtest.Assert(a1.Merge(i2).Len(), 10) + gtest.Assert(a1.Merge(s3).Len(), 12) + gtest.Assert(a1.Merge(s4).Len(), 14) + gtest.Assert(a1.Merge(s5).Len(), 16) + gtest.Assert(a1.Merge(s6).Len(), 19) + + }) +}