From 2b0da75412db3bb5c4835b3b957a5add47b8acfb Mon Sep 17 00:00:00 2001 From: John Date: Wed, 26 Jun 2019 13:55:23 +0800 Subject: [PATCH 1/7] improve ghttp.Client --- g/net/ghttp/ghttp_client_request.go | 36 ++++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/g/net/ghttp/ghttp_client_request.go b/g/net/ghttp/ghttp_client_request.go index ec629715c..70b6cfba8 100644 --- a/g/net/ghttp/ghttp_client_request.go +++ b/g/net/ghttp/ghttp_client_request.go @@ -14,13 +14,14 @@ import ( "encoding/json" "errors" "fmt" - "github.com/gogf/gf/g/os/gfile" "io" "mime/multipart" "net/http" "os" "strings" "time" + + "github.com/gogf/gf/g/os/gfile" ) // http客户端 @@ -82,7 +83,7 @@ func (c *Client) Put(url string, data ...interface{}) (*ClientResponse, error) { // POST请求提交数据,默认使用表单方式提交数据(绝大部分场景下也是如此)。 // 如果服务端对Content-Type有要求,可使用Client对象进行请求,单独设置相关属性。 // 支持文件上传,需要字段格式为:FieldName=@file: -func (c *Client) Post(url string, data ...interface{}) (*ClientResponse, error) { +func (c *Client) Post(url string, data ...interface{}) (resp *ClientResponse, err error) { if len(c.prefix) > 0 { url = c.prefix + url } @@ -119,23 +120,27 @@ func (c *Client) Post(url string, data ...interface{}) (*ClientResponse, error) } } writer.Close() - if r, err := http.NewRequest("POST", url, buffer); err != nil { + if req, err = http.NewRequest("POST", url, buffer); err != nil { return nil, err } else { - req = r req.Header.Set("Content-Type", writer.FormDataContentType()) } } else { - // 识别提交数据格式 + // 普通请求 paramBytes := []byte(param) - if r, err := http.NewRequest("POST", url, bytes.NewReader(paramBytes)); err != nil { + if req, err = http.NewRequest("POST", url, bytes.NewReader(paramBytes)); err != nil { return nil, err } else { - req = r - if json.Valid(paramBytes) { - req.Header.Set("Content-Type", "application/json") + if v, ok := c.header["Content-Type"]; ok { + // 自定义请求类型 + req.Header.Set("Content-Type", v) } else { - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + // 识别提交数据格式 + if json.Valid(paramBytes) { + req.Header.Set("Content-Type", "application/json") + } else { + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + } } } } @@ -163,23 +168,22 @@ func (c *Client) Post(url string, data ...interface{}) (*ClientResponse, error) req.SetBasicAuth(c.authUser, c.authPass) } // 执行请求 - resp := (*http.Response)(nil) + r := (*http.Response)(nil) for { - if r, err := c.Do(req); err != nil { + if r, err = c.Do(req); err != nil { if c.retryCount > 0 { c.retryCount-- } else { return nil, err } } else { - resp = r break } } - r := &ClientResponse{ + resp = &ClientResponse{ cookies: make(map[string]string), } - r.Response = resp + resp.Response = r // 浏览器模式 if c.browserMode { now := time.Now() @@ -191,7 +195,7 @@ func (c *Client) Post(url string, data ...interface{}) (*ClientResponse, error) } } } - return r, nil + return resp, nil } // DELETE请求 From e4c42bde898fcad6f6b088455aa4dfcde22f94a3 Mon Sep 17 00:00:00 2001 From: jroam Date: Wed, 26 Jun 2019 22:42:05 +0800 Subject: [PATCH 2/7] edit some imports --- g/net/gtcp/gtcp_conn.go | 1 - g/net/gtcp/gtcp_pool_pkg.go | 1 - 2 files changed, 2 deletions(-) diff --git a/g/net/gtcp/gtcp_conn.go b/g/net/gtcp/gtcp_conn.go index 171642f35..43ee80ec3 100644 --- a/g/net/gtcp/gtcp_conn.go +++ b/g/net/gtcp/gtcp_conn.go @@ -10,7 +10,6 @@ import ( "bufio" "bytes" "crypto/tls" - "errors" "io" "net" "time" diff --git a/g/net/gtcp/gtcp_pool_pkg.go b/g/net/gtcp/gtcp_pool_pkg.go index 861a4967e..03a182de6 100644 --- a/g/net/gtcp/gtcp_pool_pkg.go +++ b/g/net/gtcp/gtcp_pool_pkg.go @@ -7,7 +7,6 @@ package gtcp import ( - "errors" "time" "github.com/gogf/gf/g/internal/errors" From ebae3a492926d784714f34bebea767c6ebe8c680 Mon Sep 17 00:00:00 2001 From: jroam Date: Wed, 26 Jun 2019 22:55:19 +0800 Subject: [PATCH 3/7] Update gudp_conn.go --- g/net/gudp/gudp_conn.go | 1 - 1 file changed, 1 deletion(-) diff --git a/g/net/gudp/gudp_conn.go b/g/net/gudp/gudp_conn.go index 119d8ec00..2e6c9fdf0 100644 --- a/g/net/gudp/gudp_conn.go +++ b/g/net/gudp/gudp_conn.go @@ -7,7 +7,6 @@ package gudp import ( - "errors" "io" "net" "time" From fabf5d1ad51f0f6c5e2b858938dca1f4361213be Mon Sep 17 00:00:00 2001 From: jroam Date: Wed, 26 Jun 2019 22:57:03 +0800 Subject: [PATCH 4/7] Update gmd5.go --- g/crypto/gmd5/gmd5.go | 1 - 1 file changed, 1 deletion(-) diff --git a/g/crypto/gmd5/gmd5.go b/g/crypto/gmd5/gmd5.go index 34893d7ff..70fd7eec9 100644 --- a/g/crypto/gmd5/gmd5.go +++ b/g/crypto/gmd5/gmd5.go @@ -9,7 +9,6 @@ package gmd5 import ( "crypto/md5" - "errors" "fmt" "github.com/gogf/gf/g/internal/errors" "github.com/gogf/gf/g/util/gconv" From a5d01cb54760f292bc9eecf018844c327a53ecf1 Mon Sep 17 00:00:00 2001 From: jroam Date: Wed, 26 Jun 2019 23:08:36 +0800 Subject: [PATCH 5/7] sync gf master --- .travis.yml | 4 + .../garray/garray_z_unit_basic_test.go | 116 +++--- g/container/garray/garray_z_unit_int_test.go | 340 ++---------------- .../garray/garray_z_unit_interface_test.go | 163 ++------- .../garray/garray_z_unit_string_test.go | 264 +++----------- g/crypto/gcrc32/gcrc32_test.go | 2 - g/crypto/gmd5/gmd5.go | 5 +- g/crypto/gsha1/gsha1.go | 5 +- g/net/gtcp/gtcp_pool.go | 6 +- g/os/gmlock/gmlock_unit_lock_test.go | 133 ------- g/os/gmlock/gmlock_unit_mutex_test.go | 258 ------------- g/os/gmutex/gmutex.go | 4 +- 12 files changed, 154 insertions(+), 1146 deletions(-) delete mode 100644 g/os/gmlock/gmlock_unit_mutex_test.go diff --git a/.travis.yml b/.travis.yml index f522ba548..5c05fa0a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,10 @@ before_install: install: - cat /etc/hosts +before_script: +- find . -name "*.go" | xargs gofmt -w +- git diff --exit-code + script: - cd g - GOARCH=386 go test -v ./... diff --git a/g/container/garray/garray_z_unit_basic_test.go b/g/container/garray/garray_z_unit_basic_test.go index 2d6344795..a387bd3c0 100644 --- a/g/container/garray/garray_z_unit_basic_test.go +++ b/g/container/garray/garray_z_unit_basic_test.go @@ -17,98 +17,69 @@ import ( ) func Test_IntArray_Unique(t *testing.T) { - gtest.Case(t, func() { - expect := []int{1, 2, 3, 4, 5, 6} - array := garray.NewIntArray() - array.Append(1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6) - array.Unique() - gtest.Assert(array.Slice(), expect) - }) + expect := []int{1, 2, 3, 4, 5, 6} + array := garray.NewIntArray() + array.Append(1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6) + array.Unique() + gtest.Assert(array.Slice(), expect) } func Test_SortedIntArray1(t *testing.T) { - gtest.Case(t, func() { - expect := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - array := garray.NewSortedIntArray() - for i := 10; i > -1; i-- { - array.Add(i) - } - gtest.Assert(array.Slice(), expect) - gtest.Assert(array.Add().Slice(), expect) - gtest.Assert(array.Add(-1).Slice(), []int{-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) - }) + expect := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + array := garray.NewSortedIntArray() + for i := 10; i > -1; i-- { + array.Add(i) + } + gtest.Assert(array.Slice(), expect) } func Test_SortedIntArray2(t *testing.T) { - gtest.Case(t, func() { - expect := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - array := garray.NewSortedIntArray() - array2 := garray.NewSortedIntArray(true) - for i := 0; i <= 10; i++ { - array.Add(i) - array2.Add(i) - } - gtest.Assert(array.Slice(), expect) - gtest.Assert(array2.Slice(), expect) - }) + expect := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + array := garray.NewSortedIntArray() + for i := 0; i <= 10; i++ { + array.Add(i) + } + gtest.Assert(array.Slice(), expect) } func Test_SortedStringArray1(t *testing.T) { - gtest.Case(t, func() { - expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} - array := garray.NewSortedStringArray() - for i := 10; i > -1; i-- { - array.Add(gconv.String(i)) - } - gtest.Assert(array.Slice(), expect) - gtest.Assert(array.Add().Slice(), expect) - }) + expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} + array := garray.NewSortedStringArray() + for i := 10; i > -1; i-- { + array.Add(gconv.String(i)) + } + gtest.Assert(array.Slice(), expect) } func Test_SortedStringArray2(t *testing.T) { - gtest.Case(t, func() { - expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} - array := garray.NewSortedStringArray() - array2 := garray.NewSortedStringArray(true) - for i := 0; i <= 10; i++ { - array.Add(gconv.String(i)) - array2.Add(gconv.String(i)) - } - gtest.Assert(array.Slice(), expect) - gtest.Assert(array2.Slice(), expect) - }) + expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} + array := garray.NewSortedStringArray() + for i := 0; i <= 10; i++ { + array.Add(gconv.String(i)) + } + gtest.Assert(array.Slice(), expect) } func Test_SortedArray1(t *testing.T) { - gtest.Case(t, func() { - expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} - array := garray.NewSortedArray(func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) - }) - for i := 10; i > -1; i-- { - array.Add(gconv.String(i)) - } - gtest.Assert(array.Slice(), expect) + expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} + array := garray.NewSortedArray(func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) }) + for i := 10; i > -1; i-- { + array.Add(gconv.String(i)) + } + gtest.Assert(array.Slice(), expect) } func Test_SortedArray2(t *testing.T) { - gtest.Case(t, func() { - expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} - array := garray.NewSortedArray(func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) - }) - array2 := garray.NewSortedArray(func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) - }, 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(), expect) - gtest.Assert(array2.Slice(), expect) + expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} + array := garray.NewSortedArray(func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) }) + for i := 0; i <= 10; i++ { + array.Add(gconv.String(i)) + } + gtest.Assert(array.Slice(), expect) } func TestNewFromCopy(t *testing.T) { @@ -118,5 +89,6 @@ func TestNewFromCopy(t *testing.T) { gtest.AssertIN(array1.PopRands(2), a1) gtest.Assert(len(array1.PopRands(1)), 1) gtest.Assert(len(array1.PopRands(9)), 3) + }) } diff --git a/g/container/garray/garray_z_unit_int_test.go b/g/container/garray/garray_z_unit_int_test.go index 6cdb7590e..2a65f89f3 100644 --- a/g/container/garray/garray_z_unit_int_test.go +++ b/g/container/garray/garray_z_unit_int_test.go @@ -9,26 +9,21 @@ package garray_test import ( + "testing" + "github.com/gogf/gf/g/container/garray" "github.com/gogf/gf/g/test/gtest" - "github.com/gogf/gf/g/util/gconv" - "strings" - "testing" - "time" ) func Test_IntArray_Basic(t *testing.T) { gtest.Case(t, func() { expect := []int{0, 1, 2, 3} - expect2 := []int{} array := garray.NewIntArrayFrom(expect) - array2 := garray.NewIntArrayFrom(expect2) gtest.Assert(array.Slice(), expect) array.Set(0, 100) gtest.Assert(array.Get(0), 100) gtest.Assert(array.Get(1), 1) gtest.Assert(array.Search(100), 0) - gtest.Assert(array2.Search(7), -1) gtest.Assert(array.Contains(100), true) gtest.Assert(array.Remove(0), 100) gtest.Assert(array.Contains(100), false) @@ -49,18 +44,13 @@ func TestIntArray_Sort(t *testing.T) { expect1 := []int{0, 1, 2, 3} expect2 := []int{3, 2, 1, 0} array := garray.NewIntArray() - array2 := garray.NewIntArray(true) for i := 3; i >= 0; i-- { array.Append(i) - array2.Append(i) } - array.Sort() gtest.Assert(array.Slice(), expect1) array.Sort(true) gtest.Assert(array.Slice(), expect2) - array2.Sort(true) - gtest.Assert(array2.Slice(), expect2) }) } @@ -108,47 +98,21 @@ func TestIntArray_Range(t *testing.T) { gtest.Case(t, func() { value1 := []int{0, 1, 2, 3, 4, 5, 6} array1 := garray.NewIntArrayFrom(value1) - array2 := garray.NewIntArrayFrom(value1, true) gtest.Assert(array1.Range(0, 1), []int{0}) gtest.Assert(array1.Range(1, 2), []int{1}) gtest.Assert(array1.Range(0, 2), []int{0, 1}) gtest.Assert(array1.Range(10, 2), nil) gtest.Assert(array1.Range(-1, 10), value1) - gtest.Assert(array1.Range(8, 2), nil) - - gtest.Assert(array2.Range(2, 4), []int{2, 3}) }) } func TestIntArray_Merge(t *testing.T) { gtest.Case(t, func() { - n1 := []int{1, 2, 4, 3} - n2 := []int{7, 8, 9} - n3 := []int{3, 6} - - s1 := []string{"a", "b", "c"} - in1 := []interface{}{1, "a", 2, "b"} - - func1 := func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) - } - - a1 := garray.NewIntArrayFrom(n1) - b1 := garray.NewStringArrayFrom(s1) - b2 := garray.NewIntArrayFrom(n3) - b3 := garray.NewArrayFrom(in1) - b4 := garray.NewSortedStringArrayFrom(s1) - b5 := garray.NewSortedIntArrayFrom(n3) - b6 := garray.NewSortedArrayFrom(in1, func1) - - gtest.Assert(a1.Merge(n2).Len(), 7) - gtest.Assert(a1.Merge(n3).Len(), 9) - gtest.Assert(a1.Merge(b1).Len(), 12) - gtest.Assert(a1.Merge(b2).Len(), 14) - gtest.Assert(a1.Merge(b3).Len(), 18) - gtest.Assert(a1.Merge(b4).Len(), 21) - gtest.Assert(a1.Merge(b5).Len(), 23) - gtest.Assert(a1.Merge(b6).Len(), 27) + a1 := []int{0, 1, 2, 3} + a2 := []int{4, 5, 6, 7} + array1 := garray.NewIntArrayFrom(a1) + array2 := garray.NewIntArrayFrom(a2) + gtest.Assert(array1.Merge(array2).Slice(), []int{0, 1, 2, 3, 4, 5, 6, 7}) }) } @@ -160,7 +124,6 @@ func TestIntArray_Fill(t *testing.T) { array2 := garray.NewIntArrayFrom(a2) gtest.Assert(array1.Fill(1, 2, 100).Slice(), []int{0, 100, 100}) gtest.Assert(array2.Fill(0, 2, 100).Slice(), []int{100, 100}) - gtest.Assert(array2.Fill(-1, 2, 100).Slice(), []int{100, 100}) }) } @@ -169,8 +132,7 @@ func TestIntArray_Chunk(t *testing.T) { a1 := []int{1, 2, 3, 4, 5} array1 := garray.NewIntArrayFrom(a1) chunks := array1.Chunk(2) - chunks2 := array1.Chunk(0) - gtest.Assert(chunks2, nil) + gtest.Assert(len(chunks), 3) gtest.Assert(chunks[0], []int{1, 2}) gtest.Assert(chunks[1], []int{3, 4}) gtest.Assert(chunks[2], []int{5}) @@ -191,7 +153,6 @@ func TestIntArray_SubSlice(t *testing.T) { gtest.Case(t, func() { a1 := []int{0, 1, 2, 3, 4, 5, 6} array1 := garray.NewIntArrayFrom(a1) - array2 := garray.NewIntArrayFrom(a1, true) gtest.Assert(array1.SubSlice(6), []int{6}) gtest.Assert(array1.SubSlice(5), []int{5, 6}) gtest.Assert(array1.SubSlice(8), nil) @@ -207,7 +168,6 @@ func TestIntArray_SubSlice(t *testing.T) { gtest.Assert(array1.SubSlice(-9, 3), nil) gtest.Assert(array1.SubSlice(1, -1), []int{0}) gtest.Assert(array1.SubSlice(1, -3), nil) - gtest.Assert(array2.SubSlice(1, 2), []int{1, 2}) }) } @@ -233,6 +193,7 @@ func TestIntArray_PopRands(t *testing.T) { ns2 := array.PopRands(7) gtest.AssertIN(len(ns2), 6) gtest.AssertIN(ns2, []int{100, 200, 300, 400, 500, 600}) + }) } @@ -293,10 +254,13 @@ func TestSortedIntArray_SetArray(t *testing.T) { func TestSortedIntArray_Sort(t *testing.T) { gtest.Case(t, func() { a1 := []int{0, 3, 2, 1} + array1 := garray.NewSortedIntArrayFrom(a1) array2 := array1.Sort() + gtest.Assert(array2.Len(), 4) gtest.Assert(array2, []int{0, 1, 2, 3}) + }) } @@ -332,6 +296,7 @@ func TestSortedIntArray_Remove(t *testing.T) { i3 = array2.Remove(1) gtest.Assert(array2.Search(4), -1) gtest.Assert(i3, 4) + }) } @@ -343,6 +308,7 @@ func TestSortedIntArray_PopLeft(t *testing.T) { gtest.Assert(i1, 1) gtest.Assert(array1.Len(), 3) gtest.Assert(array1.Search(1), -1) + }) } @@ -382,6 +348,7 @@ func TestSortedIntArray_PopRands(t *testing.T) { gtest.Assert(array2.Len(), 0) gtest.Assert(len(ns2), 4) gtest.AssertIN(ns2, []int{1, 3, 5, 2}) + }) } @@ -398,6 +365,7 @@ func TestSortedIntArray_PopLefts(t *testing.T) { ns2 := array2.PopLefts(5) gtest.Assert(array2.Len(), 0) gtest.AssertIN(ns2, []int{1, 3, 5, 2}) + }) } @@ -421,7 +389,6 @@ func TestSortedIntArray_Range(t *testing.T) { gtest.Case(t, func() { a1 := []int{1, 3, 5, 2, 6, 7} array1 := garray.NewSortedIntArrayFrom(a1) - array2 := garray.NewSortedIntArrayFrom(a1, true) ns1 := array1.Range(1, 4) gtest.Assert(len(ns1), 3) gtest.Assert(ns1, []int{2, 3, 5}) @@ -435,8 +402,6 @@ func TestSortedIntArray_Range(t *testing.T) { nsl := array1.Range(5, 8) gtest.Assert(len(nsl), 1) - ns4 := array2.Range(2, 5) - gtest.Assert(len(ns4), 3) }) } @@ -453,6 +418,7 @@ func TestSortedIntArray_Contains(t *testing.T) { gtest.Case(t, func() { a1 := []int{1, 3, 5} array1 := garray.NewSortedIntArrayFrom(a1) + //gtest.Assert(array1.Contains(3),true) //todo 这一行应该返回true gtest.Assert(array1.Contains(4), false) }) } @@ -473,6 +439,7 @@ func TestSortedIntArray_Clear(t *testing.T) { array1 := garray.NewSortedIntArrayFrom(a1) array1.Clear() gtest.Assert(array1.Len(), 0) + }) } @@ -486,6 +453,7 @@ func TestSortedIntArray_Chunk(t *testing.T) { gtest.Assert(ns1[0], []int{1, 2}) gtest.Assert(ns1[2], []int{5}) gtest.Assert(len(ns2), 0) + }) } @@ -507,13 +475,6 @@ func TestSortedIntArray_SubSlice(t *testing.T) { ns4 := array1.SubSlice(3, 1) gtest.Assert(len(ns4), 1) gtest.Assert(ns4, []int{4}) - - array3 := garray.NewSortedIntArrayFrom(a1, true) - gtest.Assert(array3.SubSlice(2, 2), []int{3, 4}) - gtest.Assert(array3.SubSlice(-1, 2), []int{5}) - gtest.Assert(array3.SubSlice(-9, 2), nil) - gtest.Assert(array3.SubSlice(4, -2), []int{3, 4}) - gtest.Assert(array3.SubSlice(1, -3), nil) }) } @@ -533,6 +494,7 @@ func TestSortedIntArray_Rands(t *testing.T) { ns1 := array1.Rands(2) //按每几个元素切成一个数组 gtest.AssertIN(ns1, a1) gtest.Assert(len(ns1), 2) + ns2 := array1.Rands(6) //按每几个元素切成一个数组 gtest.AssertIN(ns2, a1) gtest.Assert(len(ns2), 5) @@ -557,6 +519,7 @@ func TestSortedIntArray_SetUnique(t *testing.T) { array1.SetUnique(true) gtest.Assert(array1.Len(), 5) gtest.Assert(array1, []int{1, 2, 3, 4, 5}) + }) } @@ -568,6 +531,7 @@ func TestIntArray_SetArray(t *testing.T) { array1.SetArray(a2) gtest.Assert(array1.Len(), 2) gtest.Assert(array1, []int{6, 7}) + }) } @@ -579,6 +543,7 @@ func TestIntArray_Replace(t *testing.T) { array1 := garray.NewIntArrayFrom(a1) array1.Replace(a2) gtest.Assert(array1, []int{6, 7, 3, 5}) + array1.Replace(a3) gtest.Assert(array1, []int{9, 10, 11, 12}) }) @@ -656,262 +621,3 @@ func TestIntArray_Remove(t *testing.T) { gtest.Assert(array1.Len(), 2) }) } - -func TestSortedIntArray_LockFunc(t *testing.T) { - gtest.Case(t, func() { - n1 := []int{1, 2, 4, 3} - a1 := garray.NewSortedIntArrayFrom(n1) - - ch1 := make(chan int64, 2) - go a1.LockFunc(func(n1 []int) { //互斥锁 - for i := 1; i <= 4; i++ { - gtest.Assert(i, n1[i-1]) - } - n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 - gtest.AssertGT(t2-t1, 600) - gtest.Assert(a1.Contains(7), true) - }) - -} - -func TestSortedIntArray_RLockFunc(t *testing.T) { - gtest.Case(t, func() { - n1 := []int{1, 2, 4, 3} - a1 := garray.NewSortedIntArrayFrom(n1) - - ch1 := make(chan int64, 2) - go a1.RLockFunc(func(n1 []int) { //读锁 - for i := 1; i <= 4; i++ { - gtest.Assert(i, n1[i-1]) - } - n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, - // 防止ci抖动,以豪秒为单位 - gtest.AssertLT(t2-t1, 2) - gtest.Assert(a1.Contains(7), true) - }) -} - -func TestSortedIntArray_Merge(t *testing.T) { - gtest.Case(t, func() { - n1 := []int{1, 2, 4, 3} - n2 := []int{7, 8, 9} - n3 := []int{3, 6} - - s1 := []string{"a", "b", "c"} - in1 := []interface{}{1, "a", 2, "b"} - - func1 := func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) - } - - a1 := garray.NewSortedIntArrayFrom(n1) - b1 := garray.NewStringArrayFrom(s1) - b2 := garray.NewIntArrayFrom(n3) - b3 := garray.NewArrayFrom(in1) - b4 := garray.NewSortedStringArrayFrom(s1) - b5 := garray.NewSortedIntArrayFrom(n3) - b6 := garray.NewSortedArrayFrom(in1, func1) - - gtest.Assert(a1.Merge(n2).Len(), 7) - gtest.Assert(a1.Merge(n3).Len(), 9) - gtest.Assert(a1.Merge(b1).Len(), 12) - gtest.Assert(a1.Merge(b2).Len(), 14) - gtest.Assert(a1.Merge(b3).Len(), 18) - gtest.Assert(a1.Merge(b4).Len(), 21) - gtest.Assert(a1.Merge(b5).Len(), 23) - gtest.Assert(a1.Merge(b6).Len(), 27) - }) - -} - -func TestSortedArray_LockFunc(t *testing.T) { - gtest.Case(t, func() { - n1 := []interface{}{1, 2, 4, 3} - - func1 := func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) - } - a1 := garray.NewSortedArrayFrom(n1, func1) - - ch1 := make(chan int64, 2) - go a1.LockFunc(func(n1 []interface{}) { //互斥锁 - n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 - gtest.AssertGT(t2-t1, 600) - gtest.Assert(a1.Contains(7), true) - }) -} - -func TestSortedArray_RLockFunc(t *testing.T) { - gtest.Case(t, func() { - n1 := []interface{}{1, 2, 4, 3} - func1 := func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) - } - a1 := garray.NewSortedArrayFrom(n1, func1) - - ch1 := make(chan int64, 2) - go a1.RLockFunc(func(n1 []interface{}) { //互斥锁 - n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, - // 防止ci抖动,以豪秒为单位 - gtest.AssertLT(t2-t1, 20) - gtest.Assert(a1.Contains(7), true) - }) -} - -func TestSortedArray_Merge(t *testing.T) { - gtest.Case(t, func() { - n1 := []interface{}{1, 2, 4, 3} - n2 := []int{7, 8, 9} - n3 := []int{3, 6} - - s1 := []string{"a", "b", "c"} - in1 := []interface{}{1, "a", 2, "b"} - - func1 := func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) - } - - a1 := garray.NewSortedArrayFrom(n1, func1) - b1 := garray.NewStringArrayFrom(s1) - b2 := garray.NewIntArrayFrom(n3) - b3 := garray.NewArrayFrom(in1) - b4 := garray.NewSortedStringArrayFrom(s1) - b5 := garray.NewSortedIntArrayFrom(n3) - - gtest.Assert(a1.Merge(n2).Len(), 7) - gtest.Assert(a1.Merge(n3).Len(), 9) - gtest.Assert(a1.Merge(b1).Len(), 12) - gtest.Assert(a1.Merge(b2).Len(), 14) - gtest.Assert(a1.Merge(b3).Len(), 18) - gtest.Assert(a1.Merge(b4).Len(), 21) - gtest.Assert(a1.Merge(b5).Len(), 23) - }) -} - -func TestIntArray_SortFunc(t *testing.T) { - gtest.Case(t, func() { - n1 := []int{1, 2, 3, 5, 4} - a1 := garray.NewIntArrayFrom(n1) - - func1 := func(v1, v2 int) bool { - if v1 > v2 { - return false - } - return true - } - func2 := func(v1, v2 int) bool { - if v1 > v2 { - return true - } - return true - } - a2 := a1.SortFunc(func1) - gtest.Assert(a2, []int{1, 2, 3, 4, 5}) - a3 := a1.SortFunc(func2) - gtest.Assert(a3, []int{5, 4, 3, 2, 1}) - }) -} - -func TestIntArray_LockFunc(t *testing.T) { - gtest.Case(t, func() { - n1 := []int{1, 2, 4, 3} - a1 := garray.NewIntArrayFrom(n1) - ch1 := make(chan int64, 2) - go a1.LockFunc(func(n1 []int) { //互斥锁 - n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 - gtest.AssertGT(t2-t1, 600) - gtest.Assert(a1.Contains(7), true) - }) -} - -func TestIntArray_RLockFunc(t *testing.T) { - gtest.Case(t, func() { - n1 := []int{1, 2, 4, 3} - a1 := garray.NewIntArrayFrom(n1) - - ch1 := make(chan int64, 2) - go a1.RLockFunc(func(n1 []int) { //互斥锁 - n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, - // 防止ci抖动,以豪秒为单位 - gtest.AssertLT(t2-t1, 20) - gtest.Assert(a1.Contains(7), true) - }) -} diff --git a/g/container/garray/garray_z_unit_interface_test.go b/g/container/garray/garray_z_unit_interface_test.go index f4f0fd9a6..90ed36d6b 100644 --- a/g/container/garray/garray_z_unit_interface_test.go +++ b/g/container/garray/garray_z_unit_interface_test.go @@ -12,10 +12,8 @@ import ( "github.com/gogf/gf/g/container/garray" "github.com/gogf/gf/g/test/gtest" "github.com/gogf/gf/g/util/gconv" - "strings" "testing" - "time" ) func Test_Array_Basic(t *testing.T) { @@ -39,24 +37,6 @@ func Test_Array_Basic(t *testing.T) { array.InsertAfter(6, 400) gtest.Assert(array.Slice(), []interface{}{100, 200, 1, 2, 3, 300, 4, 400}) gtest.Assert(array.Clear().Len(), 0) - - n1 := []interface{}{0, 1, 2, 3} - a1 := garray.NewArrayFrom(n1) - i1 := a1.Remove(3) - gtest.Assert(gconv.Int(i1), 3) - i2 := a1.Remove(1) - gtest.Assert(gconv.Int(i2), 1) - gtest.Assert(a1.Len(), 2) - gtest.Assert(a1.Contains(1), false) - - a2 := garray.NewArrayFrom(n1, true) - gtest.Assert(a2.Slice(), n1) - gtest.Assert(a2.Search(100), -1) - - n2 := []interface{}{} - a3 := garray.NewArrayFrom(n2) - gtest.Assert(a3.Search(3), -1) - }) } @@ -135,42 +115,16 @@ func TestArray_Range(t *testing.T) { gtest.Assert(array1.Range(1, 2), []interface{}{1}) gtest.Assert(array1.Range(0, 2), []interface{}{0, 1}) gtest.Assert(array1.Range(-1, 10), value1) - gtest.Assert(array1.Range(9, 1), nil) - a1 := garray.NewArrayFrom(value1, true) - gtest.Assert(a1.Range(0, 1), []interface{}{0}) }) } func TestArray_Merge(t *testing.T) { gtest.Case(t, func() { - n1 := []interface{}{1, 2, 4, 3} - n2 := []int{7, 8, 9} - n3 := []int{3, 6} - - s1 := []string{"a", "b", "c"} - in1 := []interface{}{1, "a", 2, "b"} - func1 := func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) - } - - a1 := garray.NewArrayFrom(n1) - a11 := garray.NewSortedArrayFrom(n1, func1) - b1 := garray.NewStringArrayFrom(s1) - b2 := garray.NewIntArrayFrom(n3) - b3 := garray.NewArrayFrom(in1) - b4 := garray.NewSortedStringArrayFrom(s1) - b5 := garray.NewSortedIntArrayFrom(n3) - b6 := garray.NewSortedArrayFrom(n1, func1) - - gtest.Assert(a1.Merge(n2).Len(), 7) - gtest.Assert(a1.Merge(n3).Len(), 9) - gtest.Assert(a1.Merge(b1).Len(), 12) - gtest.Assert(a1.Merge(b2).Len(), 14) - gtest.Assert(a1.Merge(b3).Len(), 18) - gtest.Assert(a1.Merge(b4).Len(), 21) - gtest.Assert(a1.Merge(b5).Len(), 23) - gtest.Assert(a1.Merge(b6).Len(), 27) - gtest.Assert(a11.Merge(b6).Len(), 8) + a1 := []interface{}{0, 1, 2, 3} + a2 := []interface{}{4, 5, 6, 7} + array1 := garray.NewArrayFrom(a1) + array2 := garray.NewArrayFrom(a2) + gtest.Assert(array1.Merge(array2).Slice(), []interface{}{0, 1, 2, 3, 4, 5, 6, 7}) }) } @@ -182,7 +136,6 @@ func TestArray_Fill(t *testing.T) { array2 := garray.NewArrayFrom(a2) gtest.Assert(array1.Fill(1, 2, 100).Slice(), []interface{}{0, 100, 100}) gtest.Assert(array2.Fill(0, 2, 100).Slice(), []interface{}{100, 100}) - gtest.Assert(array2.Fill(-1, 2, 100).Slice(), []interface{}{100, 100}) }) } @@ -195,7 +148,6 @@ func TestArray_Chunk(t *testing.T) { gtest.Assert(chunks[0], []interface{}{1, 2}) gtest.Assert(chunks[1], []interface{}{3, 4}) gtest.Assert(chunks[2], []interface{}{5}) - gtest.Assert(array1.Chunk(0), nil) }) } @@ -216,19 +168,6 @@ func TestArray_SubSlice(t *testing.T) { gtest.Assert(array1.SubSlice(0, 2), []interface{}{0, 1}) gtest.Assert(array1.SubSlice(2, 2), []interface{}{2, 3}) gtest.Assert(array1.SubSlice(5, 8), []interface{}{5, 6}) - gtest.Assert(array1.SubSlice(8, 1), nil) - - array2 := garray.NewArrayFrom(a1, false) - gtest.Assert(array2.SubSlice(2, 2), []interface{}{2, 3}) - - a2 := []interface{}{0, 1, 2, 3, 4, 5, 6} - array3 := garray.NewArrayFrom(a2, true) - gtest.Assert(array3.SubSlice(2, 2), []interface{}{2, 3}) - gtest.Assert(array3.SubSlice(-1, 2), []interface{}{6}) - gtest.Assert(array3.SubSlice(-9, 2), nil) - gtest.Assert(array3.SubSlice(4, -2), []interface{}{2, 3}) - gtest.Assert(array3.SubSlice(1, -3), nil) - }) } @@ -236,8 +175,6 @@ func TestArray_Rand(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{0, 1, 2, 3, 4, 5, 6} array1 := garray.NewArrayFrom(a1) - i1 := array1.Rand() - gtest.Assert(array1.Contains(i1), true) gtest.Assert(len(array1.Rands(2)), 2) gtest.Assert(len(array1.Rands(10)), 7) gtest.AssertIN(array1.Rands(1)[0], a1) @@ -313,6 +250,7 @@ func TestArray_Sum(t *testing.T) { gtest.Assert(array1.Sum(), 6) gtest.Assert(array2.Sum(), 0) gtest.Assert(array3.Sum(), 3) + }) } @@ -394,6 +332,7 @@ func TestSortedArray_SetArray(t *testing.T) { gtest.Assert(array1.Len(), 4) gtest.Assert(array1, []interface{}{"e", "g", "h", "k"}) }) + } func TestSortedArray_Sort(t *testing.T) { @@ -407,6 +346,7 @@ func TestSortedArray_Sort(t *testing.T) { gtest.Assert(array1.Len(), 3) gtest.Assert(array1, []interface{}{"a", "c", "f"}) }) + } func TestSortedArray_Get(t *testing.T) { @@ -419,6 +359,7 @@ func TestSortedArray_Get(t *testing.T) { gtest.Assert(array1.Get(2), "f") gtest.Assert(array1.Get(1), "c") }) + } func TestSortedArray_Remove(t *testing.T) { @@ -443,6 +384,7 @@ func TestSortedArray_Remove(t *testing.T) { gtest.Assert(array1.Len(), 1) gtest.Assert(array1.Contains("d"), false) }) + } func TestSortedArray_PopLeft(t *testing.T) { @@ -457,6 +399,7 @@ func TestSortedArray_PopLeft(t *testing.T) { gtest.Assert(array1.Len(), 3) gtest.Assert(array1, []interface{}{"b", "c", "d"}) }) + } func TestSortedArray_PopRight(t *testing.T) { @@ -471,6 +414,7 @@ func TestSortedArray_PopRight(t *testing.T) { gtest.Assert(array1.Len(), 3) gtest.Assert(array1, []interface{}{"a", "b", "c"}) }) + } func TestSortedArray_PopRand(t *testing.T) { @@ -483,6 +427,7 @@ func TestSortedArray_PopRand(t *testing.T) { i1 := array1.PopRand() gtest.AssertIN(i1, []interface{}{"a", "d", "c", "b"}) gtest.Assert(array1.Len(), 3) + }) } @@ -502,6 +447,7 @@ func TestSortedArray_PopRands(t *testing.T) { gtest.Assert(len(i1), 2) gtest.AssertIN(i2, []interface{}{"a", "d", "c", "b"}) gtest.Assert(array1.Len(), 0) + }) } @@ -521,6 +467,7 @@ func TestSortedArray_PopLefts(t *testing.T) { gtest.Assert(len(i2), 4) gtest.AssertIN(i1, []interface{}{"a", "d", "c", "b", "e", "f"}) gtest.Assert(array1.Len(), 0) + }) } @@ -535,8 +482,10 @@ func TestSortedArray_PopRights(t *testing.T) { gtest.Assert(len(i1), 2) gtest.Assert(i1, []interface{}{"e", "f"}) gtest.Assert(array1.Len(), 4) + i2 := array1.PopRights(10) gtest.Assert(len(i2), 4) + }) } @@ -547,7 +496,6 @@ 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) @@ -561,10 +509,6 @@ func TestSortedArray_Range(t *testing.T) { gtest.Assert(len(i2), 2) gtest.Assert(i2, []interface{}{"e", "f"}) - i2 = array2.Range(4, 10) - gtest.Assert(len(i2), 2) - gtest.Assert(i2, []interface{}{"e", "f"}) - }) } @@ -582,6 +526,7 @@ func TestSortedArray_Sum(t *testing.T) { gtest.Assert(array1.Sum(), 0) gtest.Assert(array2.Sum(), 6) gtest.Assert(array3.Sum(), 15) + }) } @@ -597,12 +542,14 @@ func TestSortedArray_Clone(t *testing.T) { gtest.Assert(array1, array2) array1.Remove(1) gtest.AssertNE(array1, array2) + }) } func TestSortedArray_Clear(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c", "b", "e", "f"} + func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } @@ -610,12 +557,14 @@ func TestSortedArray_Clear(t *testing.T) { gtest.Assert(array1.Len(), 6) array1.Clear() gtest.Assert(array1.Len(), 0) + }) } func TestSortedArray_Chunk(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c", "b", "e"} + func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } @@ -633,11 +582,11 @@ func TestSortedArray_Chunk(t *testing.T) { func TestSortedArray_SubSlice(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c", "b", "e"} + func1 := func(v1, v2 interface{}) int { 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"}) @@ -649,20 +598,13 @@ func TestSortedArray_SubSlice(t *testing.T) { i1 = array1.SubSlice(7, 2) gtest.Assert(len(i1), 0) - i1 = array2.SubSlice(-2, 2) - gtest.Assert(len(i1), 2) - - i1 = array2.SubSlice(-8, 1) - gtest.Assert(i1, nil) - - i1 = array2.SubSlice(1, -9) - gtest.Assert(i1, nil) }) } func TestSortedArray_Rand(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c"} + func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } @@ -676,6 +618,7 @@ func TestSortedArray_Rand(t *testing.T) { func TestSortedArray_Rands(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c"} + func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } @@ -693,12 +636,14 @@ func TestSortedArray_Rands(t *testing.T) { func TestSortedArray_Join(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c"} + func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } array1 := garray.NewSortedArrayFrom(a1, func1) gtest.Assert(array1.Join(","), "a,c,d") gtest.Assert(array1.Join("."), "a.c.d") + }) } @@ -714,12 +659,14 @@ func TestSortedArray_CountValues(t *testing.T) { gtest.Assert(len(m1), 3) gtest.Assert(m1["c"], 2) gtest.Assert(m1["a"], 1) + }) } func TestSortedArray_SetUnique(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c", "c"} + func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } @@ -729,55 +676,3 @@ func TestSortedArray_SetUnique(t *testing.T) { gtest.Assert(array1, []interface{}{"a", "c", "d"}) }) } - -func TestArray_LockFunc(t *testing.T) { - gtest.Case(t, func() { - n1 := []interface{}{1, 2, 4, 3} - a1 := garray.NewArrayFrom(n1) - ch1 := make(chan int64, 2) - go a1.LockFunc(func(n1 []interface{}) { //互斥锁 - n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 - gtest.AssertGT(t2-t1, 600) - gtest.Assert(a1.Contains(7), true) - }) -} - -func TestArray_RLockFunc(t *testing.T) { - gtest.Case(t, func() { - n1 := []interface{}{1, 2, 4, 3} - a1 := garray.NewArrayFrom(n1) - - ch1 := make(chan int64, 2) - go a1.RLockFunc(func(n1 []interface{}) { //互斥锁 - n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, - // 防止ci抖动,以豪秒为单位 - gtest.AssertLT(t2-t1, 20) - gtest.Assert(a1.Contains(7), true) - }) -} diff --git a/g/container/garray/garray_z_unit_string_test.go b/g/container/garray/garray_z_unit_string_test.go index bca25e1eb..b7c912e63 100644 --- a/g/container/garray/garray_z_unit_string_test.go +++ b/g/container/garray/garray_z_unit_string_test.go @@ -14,21 +14,17 @@ import ( "github.com/gogf/gf/g/util/gconv" "strings" "testing" - "time" ) func Test_StringArray_Basic(t *testing.T) { gtest.Case(t, func() { expect := []string{"0", "1", "2", "3"} - expect2 := []string{} array := garray.NewStringArrayFrom(expect) - array2 := garray.NewStringArrayFrom(expect2) gtest.Assert(array.Slice(), expect) array.Set(0, "100") gtest.Assert(array.Get(0), 100) gtest.Assert(array.Get(1), 1) gtest.Assert(array.Search("100"), 0) - gtest.Assert(array2.Search("100"), -1) gtest.Assert(array.Contains("100"), true) gtest.Assert(array.Remove(0), 100) gtest.Assert(array.Contains("100"), false) @@ -49,17 +45,13 @@ func TestStringArray_Sort(t *testing.T) { expect1 := []string{"0", "1", "2", "3"} expect2 := []string{"3", "2", "1", "0"} array := garray.NewStringArray() - array2 := garray.NewStringArray(true) for i := 3; i >= 0; i-- { array.Append(gconv.String(i)) - array2.Append(gconv.String(i)) } array.Sort() gtest.Assert(array.Slice(), expect1) array.Sort(true) gtest.Assert(array.Slice(), expect2) - array2.Sort(true) - gtest.Assert(array2.Slice(), expect2) }) } @@ -107,13 +99,20 @@ func TestString_Range(t *testing.T) { gtest.Case(t, func() { value1 := []string{"0", "1", "2", "3", "4", "5", "6"} array1 := garray.NewStringArrayFrom(value1) - array2 := garray.NewStringArrayFrom(value1, true) gtest.Assert(array1.Range(0, 1), []interface{}{"0"}) gtest.Assert(array1.Range(1, 2), []interface{}{"1"}) gtest.Assert(array1.Range(0, 2), []interface{}{"0", "1"}) gtest.Assert(array1.Range(-1, 10), value1) - gtest.Assert(array1.Range(8, 1), nil) - gtest.Assert(len(array2.Range(2, 4)), 2) + }) +} + +func TestStringArray_Merge(t *testing.T) { + gtest.Case(t, func() { + a1 := []string{"0", "1", "2", "3"} + a2 := []string{"4", "5", "6", "7"} + array1 := garray.NewStringArrayFrom(a1) + array2 := garray.NewStringArrayFrom(a2) + gtest.Assert(array1.Merge(array2).Slice(), []string{"0", "1", "2", "3", "4", "5", "6", "7"}) }) } @@ -161,14 +160,6 @@ func TestStringArray_SubSlice(t *testing.T) { gtest.Assert(array1.SubSlice(0, 2), []string{"0", "1"}) gtest.Assert(array1.SubSlice(2, 2), []string{"2", "3"}) gtest.Assert(array1.SubSlice(5, 8), []string{"5", "6"}) - gtest.Assert(array1.SubSlice(8, 1), nil) - - array3 := garray.NewStringArrayFrom(a1, true) - gtest.Assert(array3.SubSlice(2, 2), []string{"2", "3"}) - gtest.Assert(array3.SubSlice(-1, 2), []string{"6"}) - gtest.Assert(array3.SubSlice(-9, 2), nil) - gtest.Assert(array3.SubSlice(4, -2), []string{"2", "3"}) - gtest.Assert(array3.SubSlice(1, -3), nil) }) } @@ -190,9 +181,9 @@ func TestStringArray_PopRands(t *testing.T) { a1 := []string{"a", "b", "c", "d", "e", "f", "g"} a2 := []string{"1", "2", "3", "4", "5", "6", "7"} array1 := garray.NewStringArrayFrom(a1) + //todo gtest.AssertIN(array1.PopRands(1),a1) gtest.AssertIN(array1.PopRands(1), strings.Join(a1, ",")) gtest.AssertNI(array1.PopRands(1), strings.Join(a2, ",")) - gtest.AssertNI(len(array1.PopRands(10)), 7) }) } @@ -284,6 +275,26 @@ func TestStringArray_Sum(t *testing.T) { }) } +//func TestStringArray_SortFunc(t *testing.T) { +// gtest.Case(t, func() { +// a1 := []string{"0","1","2","3","4","5","6"} +// //a2 := []string{"0","a","3","4","5","6"} +// array1 := garray.NewStringArrayFrom(a1) +// +// lesss:=func(v1,v2 string)bool{ +// if v1>v2{ +// return true +// } +// return false +// } +// gtest.Assert(array1.Len(),7) +// gtest.Assert(lesss("1","2"),false) +// gtest.Assert(array1.SortFunc(lesss("1","2")) ,false) +// +// +// }) +//} + func TestStringArray_PopRand(t *testing.T) { gtest.Case(t, func() { a1 := []string{"0", "1", "2", "3", "4", "5", "6"} @@ -308,6 +319,7 @@ func TestStringArray_CountValues(t *testing.T) { gtest.Case(t, func() { a1 := []string{"0", "1", "2", "3", "4", "4", "6"} array1 := garray.NewStringArrayFrom(a1) + m1 := array1.CountValues() gtest.Assert(len(m1), 6) gtest.Assert(m1["2"], 1) @@ -353,8 +365,9 @@ func TestSortedStringArray_Sort(t *testing.T) { gtest.Case(t, func() { a1 := []string{"a", "d", "c", "b"} array1 := garray.NewSortedStringArrayFrom(a1) + gtest.Assert(array1, []string{"a", "b", "c", "d"}) - array1.Sort() + array1.Sort() //todo 这个SortedStringArray.sort这个方法没有必要, gtest.Assert(array1.Len(), 4) gtest.Assert(array1.Contains("c"), true) gtest.Assert(array1, []string{"a", "b", "c", "d"}) @@ -367,6 +380,7 @@ func TestSortedStringArray_Get(t *testing.T) { array1 := garray.NewSortedStringArrayFrom(a1) gtest.Assert(array1.Get(2), "c") gtest.Assert(array1.Get(0), "a") + }) } @@ -472,7 +486,6 @@ 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"}) @@ -481,10 +494,9 @@ func TestSortedStringArray_Range(t *testing.T) { gtest.Assert(len(s1), 2) gtest.Assert(s1, []string{"a", "b"}) - gtest.Assert(array1.Range(4, 8), []string{"e", "f", "g"}) - gtest.Assert(array1.Range(10, 2), nil) - gtest.Assert(array2.Range(4, 8), []string{"e", "f", "g"}) - + s1 = array1.Range(4, 8) + gtest.Assert(len(s1), 3) + gtest.Assert(s1, []string{"e", "f", "g"}) }) } @@ -524,7 +536,6 @@ 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"}) @@ -535,10 +546,6 @@ func TestSortedStringArray_SubSlice(t *testing.T) { s3 := array1.SubSlice(10, 2) gtest.Assert(len(s3), 0) - gtest.Assert(array1.SubSlice(-2, 2), []string{"f", "g"}) - gtest.Assert(array1.SubSlice(-10, 2), nil) - gtest.Assert(array1.SubSlice(2, -3), nil) - gtest.Assert(array2.SubSlice(2, 3), []string{"c", "d", "e"}) }) } @@ -548,6 +555,7 @@ func TestSortedStringArray_Len(t *testing.T) { a1 := []string{"e", "a", "d", "c", "b", "f", "g"} array1 := garray.NewSortedStringArrayFrom(a1) gtest.Assert(array1.Len(), 7) + }) } @@ -556,6 +564,7 @@ func TestSortedStringArray_Rand(t *testing.T) { a1 := []string{"e", "a", "d"} array1 := garray.NewSortedStringArrayFrom(a1) gtest.AssertIN(array1.Rand(), []string{"e", "a", "d"}) + }) } @@ -590,6 +599,7 @@ func TestSortedStringArray_CountValues(t *testing.T) { m1 := array1.CountValues() gtest.Assert(m1["a"], 2) gtest.Assert(m1["d"], 1) + }) } @@ -601,7 +611,6 @@ 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) }) } @@ -625,195 +634,6 @@ func TestStringArray_Remove(t *testing.T) { s1 = array1.Remove(3) gtest.Assert(s1, "c") gtest.Assert(array1.Len(), 3) - }) -} - -func TestSortedStringArray_LockFunc(t *testing.T) { - gtest.Case(t, func() { - s1 := []string{"a", "b", "c", "d"} - a1 := garray.NewSortedStringArrayFrom(s1) - - ch1 := make(chan int64, 2) - go a1.LockFunc(func(n1 []string) { //互斥锁 - n1[3] = "e" - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 - gtest.AssertGT(t2-t1, 600) - gtest.Assert(a1.Contains("e"), 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, 2) - go a1.RLockFunc(func(n1 []string) { //读锁 - n1[3] = "e" - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, - // 防止ci抖动,以豪秒为单位 - gtest.AssertLT(t2-t1, 2) - gtest.Assert(a1.Contains("e"), true) - }) -} - -func TestSortedStringArray_Merge(t *testing.T) { - gtest.Case(t, func() { - //n1 := []int{1, 2, 4, 3} - n2 := []int{7, 8, 9} - n3 := []int{3, 6} - - s1 := []string{"a", "b", "c"} - in1 := []interface{}{1, "a", 2, "b"} - - func1 := func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) - } - - a1 := garray.NewSortedStringArrayFrom(s1) - b1 := garray.NewStringArrayFrom(s1) - b2 := garray.NewIntArrayFrom(n3) - b3 := garray.NewArrayFrom(in1) - b4 := garray.NewSortedStringArrayFrom(s1) - b5 := garray.NewSortedIntArrayFrom(n3) - b6 := garray.NewSortedArrayFrom(in1, func1) - - gtest.Assert(a1.Merge(n2).Len(), 6) - gtest.Assert(a1.Merge(n3).Len(), 8) - gtest.Assert(a1.Merge(b1).Len(), 11) - gtest.Assert(a1.Merge(b2).Len(), 13) - gtest.Assert(a1.Merge(b3).Len(), 17) - gtest.Assert(a1.Merge(b4).Len(), 20) - gtest.Assert(a1.Merge(b5).Len(), 22) - gtest.Assert(a1.Merge(b6).Len(), 26) - }) -} - -func TestStringArray_SortFunc(t *testing.T) { - gtest.Case(t, func() { - s1 := []string{"a", "b", "d", "c"} - a1 := garray.NewStringArrayFrom(s1) - func1 := func(v1, v2 string) bool { - return strings.Compare(gconv.String(v1), gconv.String(v2)) < 0 - } - func2 := func(v1, v2 string) bool { - return strings.Compare(gconv.String(v1), gconv.String(v2)) > 0 - } - - a2 := a1.SortFunc(func1) - gtest.Assert(a2, []string{"a", "b", "c", "d"}) - - a3 := a1.SortFunc(func2) - gtest.Assert(a3, []string{"d", "c", "b", "a"}) - }) - -} - -func TestStringArray_LockFunc(t *testing.T) { - gtest.Case(t, func() { - s1 := []string{"a", "b", "c", "d"} - a1 := garray.NewStringArrayFrom(s1) - - ch1 := make(chan int64, 2) - go a1.LockFunc(func(n1 []string) { //互斥锁 - n1[3] = "f" - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 - gtest.AssertGT(t2-t1, 600) - gtest.Assert(a1.Contains("f"), true) - }) -} - -func TestStringArray_RLockFunc(t *testing.T) { - gtest.Case(t, func() { - s1 := []string{"a", "b", "c", "d"} - a1 := garray.NewStringArrayFrom(s1) - - ch1 := make(chan int64, 2) - go a1.RLockFunc(func(n1 []string) { //读锁 - n1[2] = "g" - time.Sleep(1 * time.Second) //暂停一秒 - }) - - go func() { - time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - a1.Len() - ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) - }() - - t1 := <-ch1 - t2 := <-ch1 - // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, - // 防止ci抖动,以豪秒为单位 - gtest.AssertLT(t2-t1, 2) - gtest.Assert(a1.Contains("g"), true) - }) -} - -func TestStringArray_Merge(t *testing.T) { - gtest.Case(t, func() { - //n1 := []int{1, 2, 4, 3} - n2 := []int{7, 8, 9} - n3 := []int{3, 6} - - s1 := []string{"a", "b", "c"} - in1 := []interface{}{1, "a", 2, "b"} - - func1 := func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) - } - - a1 := garray.NewStringArrayFrom(s1) - b1 := garray.NewStringArrayFrom(s1) - b2 := garray.NewIntArrayFrom(n3) - b3 := garray.NewArrayFrom(in1) - b4 := garray.NewSortedStringArrayFrom(s1) - b5 := garray.NewSortedIntArrayFrom(n3) - b6 := garray.NewSortedArrayFrom(in1, func1) - - gtest.Assert(a1.Merge(n2).Len(), 6) - gtest.Assert(a1.Merge(n3).Len(), 8) - gtest.Assert(a1.Merge(b1).Len(), 11) - gtest.Assert(a1.Merge(b2).Len(), 13) - gtest.Assert(a1.Merge(b3).Len(), 17) - gtest.Assert(a1.Merge(b4).Len(), 20) - gtest.Assert(a1.Merge(b5).Len(), 22) - gtest.Assert(a1.Merge(b6).Len(), 26) + }) } diff --git a/g/crypto/gcrc32/gcrc32_test.go b/g/crypto/gcrc32/gcrc32_test.go index f1977d098..6472a7a01 100644 --- a/g/crypto/gcrc32/gcrc32_test.go +++ b/g/crypto/gcrc32/gcrc32_test.go @@ -11,8 +11,6 @@ package gcrc32_test import ( "testing" - "github.com/gogf/gf/g/crypto/gmd5" - "github.com/gogf/gf/g/crypto/gcrc32" "github.com/gogf/gf/g/crypto/gmd5" "github.com/gogf/gf/g/test/gtest" diff --git a/g/crypto/gmd5/gmd5.go b/g/crypto/gmd5/gmd5.go index 70fd7eec9..1a9a56ea3 100644 --- a/g/crypto/gmd5/gmd5.go +++ b/g/crypto/gmd5/gmd5.go @@ -10,10 +10,11 @@ package gmd5 import ( "crypto/md5" "fmt" - "github.com/gogf/gf/g/internal/errors" - "github.com/gogf/gf/g/util/gconv" "io" "os" + + "github.com/gogf/gf/g/internal/errors" + "github.com/gogf/gf/g/util/gconv" ) // Encrypt encrypts any type of variable using MD5 algorithms. diff --git a/g/crypto/gsha1/gsha1.go b/g/crypto/gsha1/gsha1.go index 7ab16c27a..e38a8299c 100644 --- a/g/crypto/gsha1/gsha1.go +++ b/g/crypto/gsha1/gsha1.go @@ -10,10 +10,11 @@ package gsha1 import ( "crypto/sha1" "encoding/hex" - "github.com/gogf/gf/g/internal/errors" - "github.com/gogf/gf/g/util/gconv" "io" "os" + + "github.com/gogf/gf/g/internal/errors" + "github.com/gogf/gf/g/util/gconv" ) // Encrypt encrypts any type of variable using SHA1 algorithms. diff --git a/g/net/gtcp/gtcp_pool.go b/g/net/gtcp/gtcp_pool.go index 1f3ceaaf1..ec706e344 100644 --- a/g/net/gtcp/gtcp_pool.go +++ b/g/net/gtcp/gtcp_pool.go @@ -7,10 +7,12 @@ package gtcp import ( + "time" + + "github.com/gogf/gf/g/internal/errors" + "github.com/gogf/gf/g/container/gmap" "github.com/gogf/gf/g/container/gpool" - "github.com/gogf/gf/g/internal/errors" - "time" ) // 链接池链接对象 diff --git a/g/os/gmlock/gmlock_unit_lock_test.go b/g/os/gmlock/gmlock_unit_lock_test.go index c9ce524a8..da1132d4b 100644 --- a/g/os/gmlock/gmlock_unit_lock_test.go +++ b/g/os/gmlock/gmlock_unit_lock_test.go @@ -98,62 +98,7 @@ func Test_Locker_TryLock(t *testing.T) { time.Sleep(300 * time.Millisecond) gtest.Assert(array.Len(), 2) }) -} -func Test_Locker_LockFunc(t *testing.T) { - //no expire - gtest.Case(t, func() { - key := "testLockFunc" - array := garray.New() - go func() { - gmlock.LockFunc(key, func() { - array.Append(1) - time.Sleep(50 * time.Millisecond) - }) // - }() - go func() { - time.Sleep(10 * time.Millisecond) - gmlock.LockFunc(key, func() { - array.Append(1) - }) - }() - time.Sleep(10 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(20 * time.Millisecond) - gtest.Assert(array.Len(), 1) // - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 2) - }) -} - -func Test_Locker_TryLockFunc(t *testing.T) { - //no expire - gtest.Case(t, func() { - key := "testTryLockFunc" - array := garray.New() - go func() { - gmlock.TryLockFunc(key, func() { - array.Append(1) - time.Sleep(50 * time.Millisecond) - }) - }() - go func() { - time.Sleep(10 * time.Millisecond) - gmlock.TryLockFunc(key, func() { - array.Append(1) - }) - }() - go func() { - time.Sleep(70 * time.Millisecond) - gmlock.TryLockFunc(key, func() { - array.Append(1) - }) - }() - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(100 * time.Millisecond) - gtest.Assert(array.Len(), 2) - }) } func Test_Locker_LockFunc(t *testing.T) { @@ -180,30 +125,6 @@ func Test_Locker_LockFunc(t *testing.T) { time.Sleep(200 * time.Millisecond) gtest.Assert(array.Len(), 2) }) - - //expire - gtest.Case(t, func() { - key := "testLockFuncExpire" - array := garray.New() - go func() { - gmlock.LockFunc(key, func() { - array.Append(1) - time.Sleep(200 * time.Millisecond) - }, 100*time.Millisecond) // - }() - go func() { - time.Sleep(50 * time.Millisecond) - gmlock.LockFunc(key, func() { - array.Append(1) - }) - }() - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(100 * time.Millisecond) - gtest.Assert(array.Len(), 2) // - time.Sleep(350 * time.Millisecond) - gtest.Assert(array.Len(), 2) - }) } func Test_Locker_TryLockFunc(t *testing.T) { //no expire @@ -233,58 +154,4 @@ func Test_Locker_TryLockFunc(t *testing.T) { time.Sleep(400 * time.Millisecond) gtest.Assert(array.Len(), 2) }) - //expire1 - gtest.Case(t, func() { - key := "testTryLockFuncExpire1" - array := garray.New() - go func() { - gmlock.TryLockFunc(key, func() { - array.Append(1) - }, 50*time.Millisecond) - }() - go func() { - time.Sleep(10 * time.Millisecond) - gmlock.TryLockFunc(key, func() { - array.Append(1) - }) - }() - go func() { - time.Sleep(70 * time.Millisecond) - gmlock.TryLockFunc(key, func() { - array.Append(1) - }) - }() - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 2) - time.Sleep(100 * time.Millisecond) - gtest.Assert(array.Len(), 3) - }) - - //expire2 - gtest.Case(t, func() { - key := "testTryLockFuncExpire2" - array := garray.New() - go func() { - gmlock.TryLockFunc(key, func() { - array.Append(1) - time.Sleep(100 * time.Millisecond) - }, 50*time.Millisecond) //unlock after expire, before func finish. - }() - go func() { - time.Sleep(10 * time.Millisecond) - gmlock.TryLockFunc(key, func() { - array.Append(1) - }) - }() - go func() { - time.Sleep(70 * time.Millisecond) - gmlock.TryLockFunc(key, func() { - array.Append(1) - }) - }() - time.Sleep(10 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(70 * time.Millisecond) - gtest.Assert(array.Len(), 2) - }) } diff --git a/g/os/gmlock/gmlock_unit_mutex_test.go b/g/os/gmlock/gmlock_unit_mutex_test.go deleted file mode 100644 index 0e0b245d3..000000000 --- a/g/os/gmlock/gmlock_unit_mutex_test.go +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://github.com/gogf/gf. - -package gmlock_test - -import ( - "testing" - "time" - - "github.com/gogf/gf/g/container/garray" - "github.com/gogf/gf/g/os/gmlock" - "github.com/gogf/gf/g/test/gtest" -) - -func Test_Mutex_RUnlock(t *testing.T) { - gtest.Case(t, func() { - mu := gmlock.NewMutex() - for index := 0; index < 1000; index++ { - go func() { - mu.RLockFunc(func() { - time.Sleep(100 * time.Millisecond) - }) - }() - } - time.Sleep(10 * time.Millisecond) - gtest.Assert(mu.IsRLocked(), true) - gtest.Assert(mu.IsLocked(), true) - gtest.Assert(mu.IsWLocked(), false) - for index := 0; index < 1000; index++ { - go func() { - mu.RUnlock() - }() - } - time.Sleep(150 * time.Millisecond) - gtest.Assert(mu.IsRLocked(), false) - - }) -} - -func Test_Mutex_IsLocked(t *testing.T) { - gtest.Case(t, func() { - mu := gmlock.NewMutex() - go func() { - mu.LockFunc(func() { - time.Sleep(100 * time.Millisecond) - }) - }() - time.Sleep(10 * time.Millisecond) - gtest.Assert(mu.IsLocked(), true) - gtest.Assert(mu.IsWLocked(), true) - gtest.Assert(mu.IsRLocked(), false) - time.Sleep(110 * time.Millisecond) - gtest.Assert(mu.IsLocked(), false) - gtest.Assert(mu.IsWLocked(), false) - - go func() { - mu.RLockFunc(func() { - time.Sleep(100 * time.Millisecond) - }) - }() - time.Sleep(10 * time.Millisecond) - gtest.Assert(mu.IsRLocked(), true) - gtest.Assert(mu.IsLocked(), true) - gtest.Assert(mu.IsWLocked(), false) - time.Sleep(110 * time.Millisecond) - gtest.Assert(mu.IsRLocked(), false) - }) -} - -func Test_Mutex_Unlock(t *testing.T) { - gtest.Case(t, func() { - mu := gmlock.NewMutex() - array := garray.New() - go func() { - mu.LockFunc(func() { - array.Append(1) - time.Sleep(100 * time.Millisecond) - }) - }() - go func() { - time.Sleep(50 * time.Millisecond) - mu.LockFunc(func() { - array.Append(1) - }) - }() - go func() { - time.Sleep(50 * time.Millisecond) - mu.LockFunc(func() { - array.Append(1) - }) - }() - - go func() { - time.Sleep(60 * time.Millisecond) - mu.Unlock() - mu.Unlock() - mu.Unlock() - }() - - time.Sleep(20 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 3) - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 3) - }) -} - -func Test_Mutex_LockFunc(t *testing.T) { - gtest.Case(t, func() { - mu := gmlock.NewMutex() - array := garray.New() - go func() { - mu.LockFunc(func() { - array.Append(1) - time.Sleep(100 * time.Millisecond) - }) - }() - go func() { - time.Sleep(50 * time.Millisecond) - mu.LockFunc(func() { - array.Append(1) - }) - }() - time.Sleep(20 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 2) - }) -} - -func Test_Mutex_TryLockFunc(t *testing.T) { - gtest.Case(t, func() { - mu := gmlock.NewMutex() - array := garray.New() - go func() { - mu.LockFunc(func() { - array.Append(1) - time.Sleep(100 * time.Millisecond) - }) - }() - go func() { - time.Sleep(50 * time.Millisecond) - mu.TryLockFunc(func() { - array.Append(1) - }) - }() - go func() { - time.Sleep(110 * time.Millisecond) - mu.TryLockFunc(func() { - array.Append(1) - }) - }() - time.Sleep(20 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 2) - }) -} - -func Test_Mutex_RLockFunc(t *testing.T) { - gtest.Case(t, func() { - mu := gmlock.NewMutex() - array := garray.New() - go func() { - mu.LockFunc(func() { - array.Append(1) - time.Sleep(100 * time.Millisecond) - }) - }() - go func() { - time.Sleep(50 * time.Millisecond) - mu.RLockFunc(func() { - array.Append(1) - time.Sleep(100 * time.Millisecond) - }) - }() - time.Sleep(20 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(50 * time.Millisecond) - gtest.Assert(array.Len(), 2) - }) - - gtest.Case(t, func() { - mu := gmlock.NewMutex() - array := garray.New() - go func() { - time.Sleep(50 * time.Millisecond) - mu.RLockFunc(func() { - array.Append(1) - time.Sleep(100 * time.Millisecond) - }) - }() - go func() { - time.Sleep(50 * time.Millisecond) - mu.RLockFunc(func() { - array.Append(1) - time.Sleep(100 * time.Millisecond) - }) - }() - go func() { - time.Sleep(50 * time.Millisecond) - mu.RLockFunc(func() { - array.Append(1) - time.Sleep(100 * time.Millisecond) - }) - }() - gtest.Assert(array.Len(), 0) - time.Sleep(80 * time.Millisecond) - gtest.Assert(array.Len(), 3) - }) -} - -func Test_Mutex_TryRLockFunc(t *testing.T) { - gtest.Case(t, func() { - mu := gmlock.NewMutex() - array := garray.New() - go func() { - mu.LockFunc(func() { - array.Append(1) - time.Sleep(500 * time.Millisecond) - }) - }() - go func() { - time.Sleep(200 * time.Millisecond) - mu.TryRLockFunc(func() { - array.Append(1) - }) - }() - go func() { - time.Sleep(700 * time.Millisecond) - mu.TryRLockFunc(func() { - array.Append(1) - }) - }() - go func() { - time.Sleep(700 * time.Millisecond) - mu.TryRLockFunc(func() { - array.Append(1) - }) - }() - time.Sleep(100 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(500 * time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(500 * time.Millisecond) - gtest.Assert(array.Len(), 3) - }) -} diff --git a/g/os/gmutex/gmutex.go b/g/os/gmutex/gmutex.go index 6217520e2..7acc97df9 100644 --- a/g/os/gmutex/gmutex.go +++ b/g/os/gmutex/gmutex.go @@ -8,9 +8,10 @@ package gmutex import ( - "github.com/gogf/gf/g/container/gtype" "math" "runtime" + + "github.com/gogf/gf/g/container/gtype" ) // The high level Mutex, which implements more rich features for mutex. @@ -136,7 +137,6 @@ func (m *Mutex) TryRLock() bool { } else { return false } - m.locking.Set(false) } } From 56588f3f7ff8da1d4af39b792caa8c4a64067f1c Mon Sep 17 00:00:00 2001 From: jroam Date: Wed, 26 Jun 2019 23:29:47 +0800 Subject: [PATCH 6/7] add some garray unit tests --- .../garray/garray_z_unit_basic_test.go | 116 +++--- g/container/garray/garray_z_unit_int_test.go | 340 ++++++++++++++++-- .../garray/garray_z_unit_interface_test.go | 163 +++++++-- .../garray/garray_z_unit_string_test.go | 264 +++++++++++--- 4 files changed, 745 insertions(+), 138 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..2d6344795 100644 --- a/g/container/garray/garray_z_unit_basic_test.go +++ b/g/container/garray/garray_z_unit_basic_test.go @@ -17,69 +17,98 @@ import ( ) func Test_IntArray_Unique(t *testing.T) { - expect := []int{1, 2, 3, 4, 5, 6} - array := garray.NewIntArray() - array.Append(1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6) - array.Unique() - gtest.Assert(array.Slice(), expect) + gtest.Case(t, func() { + expect := []int{1, 2, 3, 4, 5, 6} + array := garray.NewIntArray() + array.Append(1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6) + array.Unique() + gtest.Assert(array.Slice(), expect) + }) } func Test_SortedIntArray1(t *testing.T) { - expect := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - array := garray.NewSortedIntArray() - for i := 10; i > -1; i-- { - array.Add(i) - } - gtest.Assert(array.Slice(), expect) + gtest.Case(t, func() { + expect := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + array := garray.NewSortedIntArray() + for i := 10; i > -1; i-- { + array.Add(i) + } + gtest.Assert(array.Slice(), expect) + gtest.Assert(array.Add().Slice(), expect) + gtest.Assert(array.Add(-1).Slice(), []int{-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + }) } func Test_SortedIntArray2(t *testing.T) { - expect := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - array := garray.NewSortedIntArray() - for i := 0; i <= 10; i++ { - array.Add(i) - } - gtest.Assert(array.Slice(), expect) + gtest.Case(t, func() { + expect := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + array := garray.NewSortedIntArray() + array2 := garray.NewSortedIntArray(true) + for i := 0; i <= 10; i++ { + array.Add(i) + array2.Add(i) + } + gtest.Assert(array.Slice(), expect) + gtest.Assert(array2.Slice(), expect) + }) } func Test_SortedStringArray1(t *testing.T) { - expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} - array := garray.NewSortedStringArray() - for i := 10; i > -1; i-- { - array.Add(gconv.String(i)) - } - gtest.Assert(array.Slice(), expect) + gtest.Case(t, func() { + expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} + array := garray.NewSortedStringArray() + for i := 10; i > -1; i-- { + array.Add(gconv.String(i)) + } + gtest.Assert(array.Slice(), expect) + gtest.Assert(array.Add().Slice(), expect) + }) } func Test_SortedStringArray2(t *testing.T) { - expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} - array := garray.NewSortedStringArray() - for i := 0; i <= 10; i++ { - array.Add(gconv.String(i)) - } - gtest.Assert(array.Slice(), expect) + gtest.Case(t, func() { + expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} + array := garray.NewSortedStringArray() + array2 := garray.NewSortedStringArray(true) + for i := 0; i <= 10; i++ { + array.Add(gconv.String(i)) + array2.Add(gconv.String(i)) + } + gtest.Assert(array.Slice(), expect) + gtest.Assert(array2.Slice(), expect) + }) } func Test_SortedArray1(t *testing.T) { - expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} - array := garray.NewSortedArray(func(v1, v2 interface{}) int { - return strings.Compare(gconv.String(v1), gconv.String(v2)) + gtest.Case(t, func() { + expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} + array := garray.NewSortedArray(func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + }) + for i := 10; i > -1; i-- { + array.Add(gconv.String(i)) + } + gtest.Assert(array.Slice(), expect) }) - for i := 10; i > -1; i-- { - array.Add(gconv.String(i)) - } - gtest.Assert(array.Slice(), expect) } 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 { - return strings.Compare(gconv.String(v1), gconv.String(v2)) + gtest.Case(t, func() { + expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"} + array := garray.NewSortedArray(func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + }) + array2 := garray.NewSortedArray(func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + }, 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(), expect) + gtest.Assert(array2.Slice(), expect) }) - for i := 0; i <= 10; i++ { - array.Add(gconv.String(i)) - } - gtest.Assert(array.Slice(), expect) } func TestNewFromCopy(t *testing.T) { @@ -89,6 +118,5 @@ func TestNewFromCopy(t *testing.T) { gtest.AssertIN(array1.PopRands(2), a1) gtest.Assert(len(array1.PopRands(1)), 1) gtest.Assert(len(array1.PopRands(9)), 3) - }) } diff --git a/g/container/garray/garray_z_unit_int_test.go b/g/container/garray/garray_z_unit_int_test.go index 2a65f89f3..6cdb7590e 100644 --- a/g/container/garray/garray_z_unit_int_test.go +++ b/g/container/garray/garray_z_unit_int_test.go @@ -9,21 +9,26 @@ package garray_test import ( - "testing" - "github.com/gogf/gf/g/container/garray" "github.com/gogf/gf/g/test/gtest" + "github.com/gogf/gf/g/util/gconv" + "strings" + "testing" + "time" ) func Test_IntArray_Basic(t *testing.T) { gtest.Case(t, func() { expect := []int{0, 1, 2, 3} + expect2 := []int{} array := garray.NewIntArrayFrom(expect) + array2 := garray.NewIntArrayFrom(expect2) gtest.Assert(array.Slice(), expect) array.Set(0, 100) gtest.Assert(array.Get(0), 100) gtest.Assert(array.Get(1), 1) gtest.Assert(array.Search(100), 0) + gtest.Assert(array2.Search(7), -1) gtest.Assert(array.Contains(100), true) gtest.Assert(array.Remove(0), 100) gtest.Assert(array.Contains(100), false) @@ -44,13 +49,18 @@ func TestIntArray_Sort(t *testing.T) { expect1 := []int{0, 1, 2, 3} expect2 := []int{3, 2, 1, 0} array := garray.NewIntArray() + array2 := garray.NewIntArray(true) for i := 3; i >= 0; i-- { array.Append(i) + array2.Append(i) } + array.Sort() gtest.Assert(array.Slice(), expect1) array.Sort(true) gtest.Assert(array.Slice(), expect2) + array2.Sort(true) + gtest.Assert(array2.Slice(), expect2) }) } @@ -98,21 +108,47 @@ func TestIntArray_Range(t *testing.T) { gtest.Case(t, func() { value1 := []int{0, 1, 2, 3, 4, 5, 6} array1 := garray.NewIntArrayFrom(value1) + array2 := garray.NewIntArrayFrom(value1, true) gtest.Assert(array1.Range(0, 1), []int{0}) gtest.Assert(array1.Range(1, 2), []int{1}) gtest.Assert(array1.Range(0, 2), []int{0, 1}) gtest.Assert(array1.Range(10, 2), nil) gtest.Assert(array1.Range(-1, 10), value1) + gtest.Assert(array1.Range(8, 2), nil) + + gtest.Assert(array2.Range(2, 4), []int{2, 3}) }) } func TestIntArray_Merge(t *testing.T) { gtest.Case(t, func() { - a1 := []int{0, 1, 2, 3} - a2 := []int{4, 5, 6, 7} - array1 := garray.NewIntArrayFrom(a1) - array2 := garray.NewIntArrayFrom(a2) - gtest.Assert(array1.Merge(array2).Slice(), []int{0, 1, 2, 3, 4, 5, 6, 7}) + n1 := []int{1, 2, 4, 3} + n2 := []int{7, 8, 9} + n3 := []int{3, 6} + + s1 := []string{"a", "b", "c"} + in1 := []interface{}{1, "a", 2, "b"} + + func1 := func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + } + + a1 := garray.NewIntArrayFrom(n1) + b1 := garray.NewStringArrayFrom(s1) + b2 := garray.NewIntArrayFrom(n3) + b3 := garray.NewArrayFrom(in1) + b4 := garray.NewSortedStringArrayFrom(s1) + b5 := garray.NewSortedIntArrayFrom(n3) + b6 := garray.NewSortedArrayFrom(in1, func1) + + gtest.Assert(a1.Merge(n2).Len(), 7) + gtest.Assert(a1.Merge(n3).Len(), 9) + gtest.Assert(a1.Merge(b1).Len(), 12) + gtest.Assert(a1.Merge(b2).Len(), 14) + gtest.Assert(a1.Merge(b3).Len(), 18) + gtest.Assert(a1.Merge(b4).Len(), 21) + gtest.Assert(a1.Merge(b5).Len(), 23) + gtest.Assert(a1.Merge(b6).Len(), 27) }) } @@ -124,6 +160,7 @@ func TestIntArray_Fill(t *testing.T) { array2 := garray.NewIntArrayFrom(a2) gtest.Assert(array1.Fill(1, 2, 100).Slice(), []int{0, 100, 100}) gtest.Assert(array2.Fill(0, 2, 100).Slice(), []int{100, 100}) + gtest.Assert(array2.Fill(-1, 2, 100).Slice(), []int{100, 100}) }) } @@ -132,7 +169,8 @@ func TestIntArray_Chunk(t *testing.T) { a1 := []int{1, 2, 3, 4, 5} array1 := garray.NewIntArrayFrom(a1) chunks := array1.Chunk(2) - gtest.Assert(len(chunks), 3) + chunks2 := array1.Chunk(0) + gtest.Assert(chunks2, nil) gtest.Assert(chunks[0], []int{1, 2}) gtest.Assert(chunks[1], []int{3, 4}) gtest.Assert(chunks[2], []int{5}) @@ -153,6 +191,7 @@ func TestIntArray_SubSlice(t *testing.T) { gtest.Case(t, func() { a1 := []int{0, 1, 2, 3, 4, 5, 6} array1 := garray.NewIntArrayFrom(a1) + array2 := garray.NewIntArrayFrom(a1, true) gtest.Assert(array1.SubSlice(6), []int{6}) gtest.Assert(array1.SubSlice(5), []int{5, 6}) gtest.Assert(array1.SubSlice(8), nil) @@ -168,6 +207,7 @@ func TestIntArray_SubSlice(t *testing.T) { gtest.Assert(array1.SubSlice(-9, 3), nil) gtest.Assert(array1.SubSlice(1, -1), []int{0}) gtest.Assert(array1.SubSlice(1, -3), nil) + gtest.Assert(array2.SubSlice(1, 2), []int{1, 2}) }) } @@ -193,7 +233,6 @@ func TestIntArray_PopRands(t *testing.T) { ns2 := array.PopRands(7) gtest.AssertIN(len(ns2), 6) gtest.AssertIN(ns2, []int{100, 200, 300, 400, 500, 600}) - }) } @@ -254,13 +293,10 @@ func TestSortedIntArray_SetArray(t *testing.T) { func TestSortedIntArray_Sort(t *testing.T) { gtest.Case(t, func() { a1 := []int{0, 3, 2, 1} - array1 := garray.NewSortedIntArrayFrom(a1) array2 := array1.Sort() - gtest.Assert(array2.Len(), 4) gtest.Assert(array2, []int{0, 1, 2, 3}) - }) } @@ -296,7 +332,6 @@ func TestSortedIntArray_Remove(t *testing.T) { i3 = array2.Remove(1) gtest.Assert(array2.Search(4), -1) gtest.Assert(i3, 4) - }) } @@ -308,7 +343,6 @@ func TestSortedIntArray_PopLeft(t *testing.T) { gtest.Assert(i1, 1) gtest.Assert(array1.Len(), 3) gtest.Assert(array1.Search(1), -1) - }) } @@ -348,7 +382,6 @@ func TestSortedIntArray_PopRands(t *testing.T) { gtest.Assert(array2.Len(), 0) gtest.Assert(len(ns2), 4) gtest.AssertIN(ns2, []int{1, 3, 5, 2}) - }) } @@ -365,7 +398,6 @@ func TestSortedIntArray_PopLefts(t *testing.T) { ns2 := array2.PopLefts(5) gtest.Assert(array2.Len(), 0) gtest.AssertIN(ns2, []int{1, 3, 5, 2}) - }) } @@ -389,6 +421,7 @@ func TestSortedIntArray_Range(t *testing.T) { gtest.Case(t, func() { a1 := []int{1, 3, 5, 2, 6, 7} array1 := garray.NewSortedIntArrayFrom(a1) + array2 := garray.NewSortedIntArrayFrom(a1, true) ns1 := array1.Range(1, 4) gtest.Assert(len(ns1), 3) gtest.Assert(ns1, []int{2, 3, 5}) @@ -402,6 +435,8 @@ func TestSortedIntArray_Range(t *testing.T) { nsl := array1.Range(5, 8) gtest.Assert(len(nsl), 1) + ns4 := array2.Range(2, 5) + gtest.Assert(len(ns4), 3) }) } @@ -418,7 +453,6 @@ func TestSortedIntArray_Contains(t *testing.T) { gtest.Case(t, func() { a1 := []int{1, 3, 5} array1 := garray.NewSortedIntArrayFrom(a1) - //gtest.Assert(array1.Contains(3),true) //todo 这一行应该返回true gtest.Assert(array1.Contains(4), false) }) } @@ -439,7 +473,6 @@ func TestSortedIntArray_Clear(t *testing.T) { array1 := garray.NewSortedIntArrayFrom(a1) array1.Clear() gtest.Assert(array1.Len(), 0) - }) } @@ -453,7 +486,6 @@ func TestSortedIntArray_Chunk(t *testing.T) { gtest.Assert(ns1[0], []int{1, 2}) gtest.Assert(ns1[2], []int{5}) gtest.Assert(len(ns2), 0) - }) } @@ -475,6 +507,13 @@ func TestSortedIntArray_SubSlice(t *testing.T) { ns4 := array1.SubSlice(3, 1) gtest.Assert(len(ns4), 1) gtest.Assert(ns4, []int{4}) + + array3 := garray.NewSortedIntArrayFrom(a1, true) + gtest.Assert(array3.SubSlice(2, 2), []int{3, 4}) + gtest.Assert(array3.SubSlice(-1, 2), []int{5}) + gtest.Assert(array3.SubSlice(-9, 2), nil) + gtest.Assert(array3.SubSlice(4, -2), []int{3, 4}) + gtest.Assert(array3.SubSlice(1, -3), nil) }) } @@ -494,7 +533,6 @@ func TestSortedIntArray_Rands(t *testing.T) { ns1 := array1.Rands(2) //按每几个元素切成一个数组 gtest.AssertIN(ns1, a1) gtest.Assert(len(ns1), 2) - ns2 := array1.Rands(6) //按每几个元素切成一个数组 gtest.AssertIN(ns2, a1) gtest.Assert(len(ns2), 5) @@ -519,7 +557,6 @@ func TestSortedIntArray_SetUnique(t *testing.T) { array1.SetUnique(true) gtest.Assert(array1.Len(), 5) gtest.Assert(array1, []int{1, 2, 3, 4, 5}) - }) } @@ -531,7 +568,6 @@ func TestIntArray_SetArray(t *testing.T) { array1.SetArray(a2) gtest.Assert(array1.Len(), 2) gtest.Assert(array1, []int{6, 7}) - }) } @@ -543,7 +579,6 @@ func TestIntArray_Replace(t *testing.T) { array1 := garray.NewIntArrayFrom(a1) array1.Replace(a2) gtest.Assert(array1, []int{6, 7, 3, 5}) - array1.Replace(a3) gtest.Assert(array1, []int{9, 10, 11, 12}) }) @@ -621,3 +656,262 @@ func TestIntArray_Remove(t *testing.T) { gtest.Assert(array1.Len(), 2) }) } + +func TestSortedIntArray_LockFunc(t *testing.T) { + gtest.Case(t, func() { + n1 := []int{1, 2, 4, 3} + a1 := garray.NewSortedIntArrayFrom(n1) + + ch1 := make(chan int64, 2) + go a1.LockFunc(func(n1 []int) { //互斥锁 + for i := 1; i <= 4; i++ { + gtest.Assert(i, n1[i-1]) + } + n1[3] = 7 + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 + gtest.AssertGT(t2-t1, 600) + gtest.Assert(a1.Contains(7), true) + }) + +} + +func TestSortedIntArray_RLockFunc(t *testing.T) { + gtest.Case(t, func() { + n1 := []int{1, 2, 4, 3} + a1 := garray.NewSortedIntArrayFrom(n1) + + ch1 := make(chan int64, 2) + go a1.RLockFunc(func(n1 []int) { //读锁 + for i := 1; i <= 4; i++ { + gtest.Assert(i, n1[i-1]) + } + n1[3] = 7 + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, + // 防止ci抖动,以豪秒为单位 + gtest.AssertLT(t2-t1, 2) + gtest.Assert(a1.Contains(7), true) + }) +} + +func TestSortedIntArray_Merge(t *testing.T) { + gtest.Case(t, func() { + n1 := []int{1, 2, 4, 3} + n2 := []int{7, 8, 9} + n3 := []int{3, 6} + + s1 := []string{"a", "b", "c"} + in1 := []interface{}{1, "a", 2, "b"} + + func1 := func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + } + + a1 := garray.NewSortedIntArrayFrom(n1) + b1 := garray.NewStringArrayFrom(s1) + b2 := garray.NewIntArrayFrom(n3) + b3 := garray.NewArrayFrom(in1) + b4 := garray.NewSortedStringArrayFrom(s1) + b5 := garray.NewSortedIntArrayFrom(n3) + b6 := garray.NewSortedArrayFrom(in1, func1) + + gtest.Assert(a1.Merge(n2).Len(), 7) + gtest.Assert(a1.Merge(n3).Len(), 9) + gtest.Assert(a1.Merge(b1).Len(), 12) + gtest.Assert(a1.Merge(b2).Len(), 14) + gtest.Assert(a1.Merge(b3).Len(), 18) + gtest.Assert(a1.Merge(b4).Len(), 21) + gtest.Assert(a1.Merge(b5).Len(), 23) + gtest.Assert(a1.Merge(b6).Len(), 27) + }) + +} + +func TestSortedArray_LockFunc(t *testing.T) { + gtest.Case(t, func() { + n1 := []interface{}{1, 2, 4, 3} + + func1 := func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + } + a1 := garray.NewSortedArrayFrom(n1, func1) + + ch1 := make(chan int64, 2) + go a1.LockFunc(func(n1 []interface{}) { //互斥锁 + n1[3] = 7 + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 + gtest.AssertGT(t2-t1, 600) + gtest.Assert(a1.Contains(7), true) + }) +} + +func TestSortedArray_RLockFunc(t *testing.T) { + gtest.Case(t, func() { + n1 := []interface{}{1, 2, 4, 3} + func1 := func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + } + a1 := garray.NewSortedArrayFrom(n1, func1) + + ch1 := make(chan int64, 2) + go a1.RLockFunc(func(n1 []interface{}) { //互斥锁 + n1[3] = 7 + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, + // 防止ci抖动,以豪秒为单位 + gtest.AssertLT(t2-t1, 20) + gtest.Assert(a1.Contains(7), true) + }) +} + +func TestSortedArray_Merge(t *testing.T) { + gtest.Case(t, func() { + n1 := []interface{}{1, 2, 4, 3} + n2 := []int{7, 8, 9} + n3 := []int{3, 6} + + s1 := []string{"a", "b", "c"} + in1 := []interface{}{1, "a", 2, "b"} + + func1 := func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + } + + a1 := garray.NewSortedArrayFrom(n1, func1) + b1 := garray.NewStringArrayFrom(s1) + b2 := garray.NewIntArrayFrom(n3) + b3 := garray.NewArrayFrom(in1) + b4 := garray.NewSortedStringArrayFrom(s1) + b5 := garray.NewSortedIntArrayFrom(n3) + + gtest.Assert(a1.Merge(n2).Len(), 7) + gtest.Assert(a1.Merge(n3).Len(), 9) + gtest.Assert(a1.Merge(b1).Len(), 12) + gtest.Assert(a1.Merge(b2).Len(), 14) + gtest.Assert(a1.Merge(b3).Len(), 18) + gtest.Assert(a1.Merge(b4).Len(), 21) + gtest.Assert(a1.Merge(b5).Len(), 23) + }) +} + +func TestIntArray_SortFunc(t *testing.T) { + gtest.Case(t, func() { + n1 := []int{1, 2, 3, 5, 4} + a1 := garray.NewIntArrayFrom(n1) + + func1 := func(v1, v2 int) bool { + if v1 > v2 { + return false + } + return true + } + func2 := func(v1, v2 int) bool { + if v1 > v2 { + return true + } + return true + } + a2 := a1.SortFunc(func1) + gtest.Assert(a2, []int{1, 2, 3, 4, 5}) + a3 := a1.SortFunc(func2) + gtest.Assert(a3, []int{5, 4, 3, 2, 1}) + }) +} + +func TestIntArray_LockFunc(t *testing.T) { + gtest.Case(t, func() { + n1 := []int{1, 2, 4, 3} + a1 := garray.NewIntArrayFrom(n1) + ch1 := make(chan int64, 2) + go a1.LockFunc(func(n1 []int) { //互斥锁 + n1[3] = 7 + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 + gtest.AssertGT(t2-t1, 600) + gtest.Assert(a1.Contains(7), true) + }) +} + +func TestIntArray_RLockFunc(t *testing.T) { + gtest.Case(t, func() { + n1 := []int{1, 2, 4, 3} + a1 := garray.NewIntArrayFrom(n1) + + ch1 := make(chan int64, 2) + go a1.RLockFunc(func(n1 []int) { //互斥锁 + n1[3] = 7 + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, + // 防止ci抖动,以豪秒为单位 + gtest.AssertLT(t2-t1, 20) + gtest.Assert(a1.Contains(7), true) + }) +} diff --git a/g/container/garray/garray_z_unit_interface_test.go b/g/container/garray/garray_z_unit_interface_test.go index 90ed36d6b..f4f0fd9a6 100644 --- a/g/container/garray/garray_z_unit_interface_test.go +++ b/g/container/garray/garray_z_unit_interface_test.go @@ -12,8 +12,10 @@ import ( "github.com/gogf/gf/g/container/garray" "github.com/gogf/gf/g/test/gtest" "github.com/gogf/gf/g/util/gconv" + "strings" "testing" + "time" ) func Test_Array_Basic(t *testing.T) { @@ -37,6 +39,24 @@ func Test_Array_Basic(t *testing.T) { array.InsertAfter(6, 400) gtest.Assert(array.Slice(), []interface{}{100, 200, 1, 2, 3, 300, 4, 400}) gtest.Assert(array.Clear().Len(), 0) + + n1 := []interface{}{0, 1, 2, 3} + a1 := garray.NewArrayFrom(n1) + i1 := a1.Remove(3) + gtest.Assert(gconv.Int(i1), 3) + i2 := a1.Remove(1) + gtest.Assert(gconv.Int(i2), 1) + gtest.Assert(a1.Len(), 2) + gtest.Assert(a1.Contains(1), false) + + a2 := garray.NewArrayFrom(n1, true) + gtest.Assert(a2.Slice(), n1) + gtest.Assert(a2.Search(100), -1) + + n2 := []interface{}{} + a3 := garray.NewArrayFrom(n2) + gtest.Assert(a3.Search(3), -1) + }) } @@ -115,16 +135,42 @@ func TestArray_Range(t *testing.T) { gtest.Assert(array1.Range(1, 2), []interface{}{1}) gtest.Assert(array1.Range(0, 2), []interface{}{0, 1}) gtest.Assert(array1.Range(-1, 10), value1) + gtest.Assert(array1.Range(9, 1), nil) + a1 := garray.NewArrayFrom(value1, true) + gtest.Assert(a1.Range(0, 1), []interface{}{0}) }) } func TestArray_Merge(t *testing.T) { gtest.Case(t, func() { - a1 := []interface{}{0, 1, 2, 3} - a2 := []interface{}{4, 5, 6, 7} - array1 := garray.NewArrayFrom(a1) - array2 := garray.NewArrayFrom(a2) - gtest.Assert(array1.Merge(array2).Slice(), []interface{}{0, 1, 2, 3, 4, 5, 6, 7}) + n1 := []interface{}{1, 2, 4, 3} + n2 := []int{7, 8, 9} + n3 := []int{3, 6} + + s1 := []string{"a", "b", "c"} + in1 := []interface{}{1, "a", 2, "b"} + func1 := func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + } + + a1 := garray.NewArrayFrom(n1) + a11 := garray.NewSortedArrayFrom(n1, func1) + b1 := garray.NewStringArrayFrom(s1) + b2 := garray.NewIntArrayFrom(n3) + b3 := garray.NewArrayFrom(in1) + b4 := garray.NewSortedStringArrayFrom(s1) + b5 := garray.NewSortedIntArrayFrom(n3) + b6 := garray.NewSortedArrayFrom(n1, func1) + + gtest.Assert(a1.Merge(n2).Len(), 7) + gtest.Assert(a1.Merge(n3).Len(), 9) + gtest.Assert(a1.Merge(b1).Len(), 12) + gtest.Assert(a1.Merge(b2).Len(), 14) + gtest.Assert(a1.Merge(b3).Len(), 18) + gtest.Assert(a1.Merge(b4).Len(), 21) + gtest.Assert(a1.Merge(b5).Len(), 23) + gtest.Assert(a1.Merge(b6).Len(), 27) + gtest.Assert(a11.Merge(b6).Len(), 8) }) } @@ -136,6 +182,7 @@ func TestArray_Fill(t *testing.T) { array2 := garray.NewArrayFrom(a2) gtest.Assert(array1.Fill(1, 2, 100).Slice(), []interface{}{0, 100, 100}) gtest.Assert(array2.Fill(0, 2, 100).Slice(), []interface{}{100, 100}) + gtest.Assert(array2.Fill(-1, 2, 100).Slice(), []interface{}{100, 100}) }) } @@ -148,6 +195,7 @@ func TestArray_Chunk(t *testing.T) { gtest.Assert(chunks[0], []interface{}{1, 2}) gtest.Assert(chunks[1], []interface{}{3, 4}) gtest.Assert(chunks[2], []interface{}{5}) + gtest.Assert(array1.Chunk(0), nil) }) } @@ -168,6 +216,19 @@ func TestArray_SubSlice(t *testing.T) { gtest.Assert(array1.SubSlice(0, 2), []interface{}{0, 1}) gtest.Assert(array1.SubSlice(2, 2), []interface{}{2, 3}) gtest.Assert(array1.SubSlice(5, 8), []interface{}{5, 6}) + gtest.Assert(array1.SubSlice(8, 1), nil) + + array2 := garray.NewArrayFrom(a1, false) + gtest.Assert(array2.SubSlice(2, 2), []interface{}{2, 3}) + + a2 := []interface{}{0, 1, 2, 3, 4, 5, 6} + array3 := garray.NewArrayFrom(a2, true) + gtest.Assert(array3.SubSlice(2, 2), []interface{}{2, 3}) + gtest.Assert(array3.SubSlice(-1, 2), []interface{}{6}) + gtest.Assert(array3.SubSlice(-9, 2), nil) + gtest.Assert(array3.SubSlice(4, -2), []interface{}{2, 3}) + gtest.Assert(array3.SubSlice(1, -3), nil) + }) } @@ -175,6 +236,8 @@ func TestArray_Rand(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{0, 1, 2, 3, 4, 5, 6} array1 := garray.NewArrayFrom(a1) + i1 := array1.Rand() + gtest.Assert(array1.Contains(i1), true) gtest.Assert(len(array1.Rands(2)), 2) gtest.Assert(len(array1.Rands(10)), 7) gtest.AssertIN(array1.Rands(1)[0], a1) @@ -250,7 +313,6 @@ func TestArray_Sum(t *testing.T) { gtest.Assert(array1.Sum(), 6) gtest.Assert(array2.Sum(), 0) gtest.Assert(array3.Sum(), 3) - }) } @@ -332,7 +394,6 @@ func TestSortedArray_SetArray(t *testing.T) { gtest.Assert(array1.Len(), 4) gtest.Assert(array1, []interface{}{"e", "g", "h", "k"}) }) - } func TestSortedArray_Sort(t *testing.T) { @@ -346,7 +407,6 @@ func TestSortedArray_Sort(t *testing.T) { gtest.Assert(array1.Len(), 3) gtest.Assert(array1, []interface{}{"a", "c", "f"}) }) - } func TestSortedArray_Get(t *testing.T) { @@ -359,7 +419,6 @@ func TestSortedArray_Get(t *testing.T) { gtest.Assert(array1.Get(2), "f") gtest.Assert(array1.Get(1), "c") }) - } func TestSortedArray_Remove(t *testing.T) { @@ -384,7 +443,6 @@ func TestSortedArray_Remove(t *testing.T) { gtest.Assert(array1.Len(), 1) gtest.Assert(array1.Contains("d"), false) }) - } func TestSortedArray_PopLeft(t *testing.T) { @@ -399,7 +457,6 @@ func TestSortedArray_PopLeft(t *testing.T) { gtest.Assert(array1.Len(), 3) gtest.Assert(array1, []interface{}{"b", "c", "d"}) }) - } func TestSortedArray_PopRight(t *testing.T) { @@ -414,7 +471,6 @@ func TestSortedArray_PopRight(t *testing.T) { gtest.Assert(array1.Len(), 3) gtest.Assert(array1, []interface{}{"a", "b", "c"}) }) - } func TestSortedArray_PopRand(t *testing.T) { @@ -427,7 +483,6 @@ func TestSortedArray_PopRand(t *testing.T) { i1 := array1.PopRand() gtest.AssertIN(i1, []interface{}{"a", "d", "c", "b"}) gtest.Assert(array1.Len(), 3) - }) } @@ -447,7 +502,6 @@ func TestSortedArray_PopRands(t *testing.T) { gtest.Assert(len(i1), 2) gtest.AssertIN(i2, []interface{}{"a", "d", "c", "b"}) gtest.Assert(array1.Len(), 0) - }) } @@ -467,7 +521,6 @@ func TestSortedArray_PopLefts(t *testing.T) { gtest.Assert(len(i2), 4) gtest.AssertIN(i1, []interface{}{"a", "d", "c", "b", "e", "f"}) gtest.Assert(array1.Len(), 0) - }) } @@ -482,10 +535,8 @@ func TestSortedArray_PopRights(t *testing.T) { gtest.Assert(len(i1), 2) gtest.Assert(i1, []interface{}{"e", "f"}) gtest.Assert(array1.Len(), 4) - i2 := array1.PopRights(10) gtest.Assert(len(i2), 4) - }) } @@ -496,6 +547,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 +561,10 @@ func TestSortedArray_Range(t *testing.T) { gtest.Assert(len(i2), 2) gtest.Assert(i2, []interface{}{"e", "f"}) + i2 = array2.Range(4, 10) + gtest.Assert(len(i2), 2) + gtest.Assert(i2, []interface{}{"e", "f"}) + }) } @@ -526,7 +582,6 @@ func TestSortedArray_Sum(t *testing.T) { gtest.Assert(array1.Sum(), 0) gtest.Assert(array2.Sum(), 6) gtest.Assert(array3.Sum(), 15) - }) } @@ -542,14 +597,12 @@ func TestSortedArray_Clone(t *testing.T) { gtest.Assert(array1, array2) array1.Remove(1) gtest.AssertNE(array1, array2) - }) } func TestSortedArray_Clear(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c", "b", "e", "f"} - func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } @@ -557,14 +610,12 @@ func TestSortedArray_Clear(t *testing.T) { gtest.Assert(array1.Len(), 6) array1.Clear() gtest.Assert(array1.Len(), 0) - }) } func TestSortedArray_Chunk(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c", "b", "e"} - func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } @@ -582,11 +633,11 @@ func TestSortedArray_Chunk(t *testing.T) { func TestSortedArray_SubSlice(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c", "b", "e"} - func1 := func(v1, v2 interface{}) int { 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,13 +649,20 @@ func TestSortedArray_SubSlice(t *testing.T) { i1 = array1.SubSlice(7, 2) gtest.Assert(len(i1), 0) + i1 = array2.SubSlice(-2, 2) + gtest.Assert(len(i1), 2) + + i1 = array2.SubSlice(-8, 1) + gtest.Assert(i1, nil) + + i1 = array2.SubSlice(1, -9) + gtest.Assert(i1, nil) }) } func TestSortedArray_Rand(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c"} - func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } @@ -618,7 +676,6 @@ func TestSortedArray_Rand(t *testing.T) { func TestSortedArray_Rands(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c"} - func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } @@ -636,14 +693,12 @@ func TestSortedArray_Rands(t *testing.T) { func TestSortedArray_Join(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c"} - func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } array1 := garray.NewSortedArrayFrom(a1, func1) gtest.Assert(array1.Join(","), "a,c,d") gtest.Assert(array1.Join("."), "a.c.d") - }) } @@ -659,14 +714,12 @@ func TestSortedArray_CountValues(t *testing.T) { gtest.Assert(len(m1), 3) gtest.Assert(m1["c"], 2) gtest.Assert(m1["a"], 1) - }) } func TestSortedArray_SetUnique(t *testing.T) { gtest.Case(t, func() { a1 := []interface{}{"a", "d", "c", "c"} - func1 := func(v1, v2 interface{}) int { return strings.Compare(gconv.String(v1), gconv.String(v2)) } @@ -676,3 +729,55 @@ func TestSortedArray_SetUnique(t *testing.T) { gtest.Assert(array1, []interface{}{"a", "c", "d"}) }) } + +func TestArray_LockFunc(t *testing.T) { + gtest.Case(t, func() { + n1 := []interface{}{1, 2, 4, 3} + a1 := garray.NewArrayFrom(n1) + ch1 := make(chan int64, 2) + go a1.LockFunc(func(n1 []interface{}) { //互斥锁 + n1[3] = 7 + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 + gtest.AssertGT(t2-t1, 600) + gtest.Assert(a1.Contains(7), true) + }) +} + +func TestArray_RLockFunc(t *testing.T) { + gtest.Case(t, func() { + n1 := []interface{}{1, 2, 4, 3} + a1 := garray.NewArrayFrom(n1) + + ch1 := make(chan int64, 2) + go a1.RLockFunc(func(n1 []interface{}) { //互斥锁 + n1[3] = 7 + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, + // 防止ci抖动,以豪秒为单位 + gtest.AssertLT(t2-t1, 20) + gtest.Assert(a1.Contains(7), true) + }) +} diff --git a/g/container/garray/garray_z_unit_string_test.go b/g/container/garray/garray_z_unit_string_test.go index b7c912e63..bca25e1eb 100644 --- a/g/container/garray/garray_z_unit_string_test.go +++ b/g/container/garray/garray_z_unit_string_test.go @@ -14,17 +14,21 @@ import ( "github.com/gogf/gf/g/util/gconv" "strings" "testing" + "time" ) func Test_StringArray_Basic(t *testing.T) { gtest.Case(t, func() { expect := []string{"0", "1", "2", "3"} + expect2 := []string{} array := garray.NewStringArrayFrom(expect) + array2 := garray.NewStringArrayFrom(expect2) gtest.Assert(array.Slice(), expect) array.Set(0, "100") gtest.Assert(array.Get(0), 100) gtest.Assert(array.Get(1), 1) gtest.Assert(array.Search("100"), 0) + gtest.Assert(array2.Search("100"), -1) gtest.Assert(array.Contains("100"), true) gtest.Assert(array.Remove(0), 100) gtest.Assert(array.Contains("100"), false) @@ -45,13 +49,17 @@ func TestStringArray_Sort(t *testing.T) { expect1 := []string{"0", "1", "2", "3"} expect2 := []string{"3", "2", "1", "0"} array := garray.NewStringArray() + array2 := garray.NewStringArray(true) for i := 3; i >= 0; i-- { array.Append(gconv.String(i)) + array2.Append(gconv.String(i)) } array.Sort() gtest.Assert(array.Slice(), expect1) array.Sort(true) gtest.Assert(array.Slice(), expect2) + array2.Sort(true) + gtest.Assert(array2.Slice(), expect2) }) } @@ -99,20 +107,13 @@ func TestString_Range(t *testing.T) { gtest.Case(t, func() { value1 := []string{"0", "1", "2", "3", "4", "5", "6"} array1 := garray.NewStringArrayFrom(value1) + array2 := garray.NewStringArrayFrom(value1, true) gtest.Assert(array1.Range(0, 1), []interface{}{"0"}) gtest.Assert(array1.Range(1, 2), []interface{}{"1"}) gtest.Assert(array1.Range(0, 2), []interface{}{"0", "1"}) gtest.Assert(array1.Range(-1, 10), value1) - }) -} - -func TestStringArray_Merge(t *testing.T) { - gtest.Case(t, func() { - a1 := []string{"0", "1", "2", "3"} - a2 := []string{"4", "5", "6", "7"} - array1 := garray.NewStringArrayFrom(a1) - array2 := garray.NewStringArrayFrom(a2) - gtest.Assert(array1.Merge(array2).Slice(), []string{"0", "1", "2", "3", "4", "5", "6", "7"}) + gtest.Assert(array1.Range(8, 1), nil) + gtest.Assert(len(array2.Range(2, 4)), 2) }) } @@ -160,6 +161,14 @@ func TestStringArray_SubSlice(t *testing.T) { gtest.Assert(array1.SubSlice(0, 2), []string{"0", "1"}) gtest.Assert(array1.SubSlice(2, 2), []string{"2", "3"}) gtest.Assert(array1.SubSlice(5, 8), []string{"5", "6"}) + gtest.Assert(array1.SubSlice(8, 1), nil) + + array3 := garray.NewStringArrayFrom(a1, true) + gtest.Assert(array3.SubSlice(2, 2), []string{"2", "3"}) + gtest.Assert(array3.SubSlice(-1, 2), []string{"6"}) + gtest.Assert(array3.SubSlice(-9, 2), nil) + gtest.Assert(array3.SubSlice(4, -2), []string{"2", "3"}) + gtest.Assert(array3.SubSlice(1, -3), nil) }) } @@ -181,9 +190,9 @@ func TestStringArray_PopRands(t *testing.T) { a1 := []string{"a", "b", "c", "d", "e", "f", "g"} a2 := []string{"1", "2", "3", "4", "5", "6", "7"} array1 := garray.NewStringArrayFrom(a1) - //todo gtest.AssertIN(array1.PopRands(1),a1) gtest.AssertIN(array1.PopRands(1), strings.Join(a1, ",")) gtest.AssertNI(array1.PopRands(1), strings.Join(a2, ",")) + gtest.AssertNI(len(array1.PopRands(10)), 7) }) } @@ -275,26 +284,6 @@ func TestStringArray_Sum(t *testing.T) { }) } -//func TestStringArray_SortFunc(t *testing.T) { -// gtest.Case(t, func() { -// a1 := []string{"0","1","2","3","4","5","6"} -// //a2 := []string{"0","a","3","4","5","6"} -// array1 := garray.NewStringArrayFrom(a1) -// -// lesss:=func(v1,v2 string)bool{ -// if v1>v2{ -// return true -// } -// return false -// } -// gtest.Assert(array1.Len(),7) -// gtest.Assert(lesss("1","2"),false) -// gtest.Assert(array1.SortFunc(lesss("1","2")) ,false) -// -// -// }) -//} - func TestStringArray_PopRand(t *testing.T) { gtest.Case(t, func() { a1 := []string{"0", "1", "2", "3", "4", "5", "6"} @@ -319,7 +308,6 @@ func TestStringArray_CountValues(t *testing.T) { gtest.Case(t, func() { a1 := []string{"0", "1", "2", "3", "4", "4", "6"} array1 := garray.NewStringArrayFrom(a1) - m1 := array1.CountValues() gtest.Assert(len(m1), 6) gtest.Assert(m1["2"], 1) @@ -365,9 +353,8 @@ func TestSortedStringArray_Sort(t *testing.T) { gtest.Case(t, func() { a1 := []string{"a", "d", "c", "b"} array1 := garray.NewSortedStringArrayFrom(a1) - gtest.Assert(array1, []string{"a", "b", "c", "d"}) - array1.Sort() //todo 这个SortedStringArray.sort这个方法没有必要, + array1.Sort() gtest.Assert(array1.Len(), 4) gtest.Assert(array1.Contains("c"), true) gtest.Assert(array1, []string{"a", "b", "c", "d"}) @@ -380,7 +367,6 @@ func TestSortedStringArray_Get(t *testing.T) { array1 := garray.NewSortedStringArrayFrom(a1) gtest.Assert(array1.Get(2), "c") gtest.Assert(array1.Get(0), "a") - }) } @@ -486,6 +472,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"}) @@ -494,9 +481,10 @@ func TestSortedStringArray_Range(t *testing.T) { gtest.Assert(len(s1), 2) gtest.Assert(s1, []string{"a", "b"}) - s1 = array1.Range(4, 8) - gtest.Assert(len(s1), 3) - gtest.Assert(s1, []string{"e", "f", "g"}) + gtest.Assert(array1.Range(4, 8), []string{"e", "f", "g"}) + gtest.Assert(array1.Range(10, 2), nil) + gtest.Assert(array2.Range(4, 8), []string{"e", "f", "g"}) + }) } @@ -536,6 +524,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"}) @@ -546,6 +535,10 @@ func TestSortedStringArray_SubSlice(t *testing.T) { s3 := array1.SubSlice(10, 2) gtest.Assert(len(s3), 0) + gtest.Assert(array1.SubSlice(-2, 2), []string{"f", "g"}) + gtest.Assert(array1.SubSlice(-10, 2), nil) + gtest.Assert(array1.SubSlice(2, -3), nil) + gtest.Assert(array2.SubSlice(2, 3), []string{"c", "d", "e"}) }) } @@ -555,7 +548,6 @@ func TestSortedStringArray_Len(t *testing.T) { a1 := []string{"e", "a", "d", "c", "b", "f", "g"} array1 := garray.NewSortedStringArrayFrom(a1) gtest.Assert(array1.Len(), 7) - }) } @@ -564,7 +556,6 @@ func TestSortedStringArray_Rand(t *testing.T) { a1 := []string{"e", "a", "d"} array1 := garray.NewSortedStringArrayFrom(a1) gtest.AssertIN(array1.Rand(), []string{"e", "a", "d"}) - }) } @@ -599,7 +590,6 @@ func TestSortedStringArray_CountValues(t *testing.T) { m1 := array1.CountValues() gtest.Assert(m1["a"], 2) gtest.Assert(m1["d"], 1) - }) } @@ -611,6 +601,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) }) } @@ -634,6 +625,195 @@ func TestStringArray_Remove(t *testing.T) { s1 = array1.Remove(3) gtest.Assert(s1, "c") gtest.Assert(array1.Len(), 3) - + }) +} + +func TestSortedStringArray_LockFunc(t *testing.T) { + gtest.Case(t, func() { + s1 := []string{"a", "b", "c", "d"} + a1 := garray.NewSortedStringArrayFrom(s1) + + ch1 := make(chan int64, 2) + go a1.LockFunc(func(n1 []string) { //互斥锁 + n1[3] = "e" + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 + gtest.AssertGT(t2-t1, 600) + gtest.Assert(a1.Contains("e"), 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, 2) + go a1.RLockFunc(func(n1 []string) { //读锁 + n1[3] = "e" + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, + // 防止ci抖动,以豪秒为单位 + gtest.AssertLT(t2-t1, 2) + gtest.Assert(a1.Contains("e"), true) + }) +} + +func TestSortedStringArray_Merge(t *testing.T) { + gtest.Case(t, func() { + //n1 := []int{1, 2, 4, 3} + n2 := []int{7, 8, 9} + n3 := []int{3, 6} + + s1 := []string{"a", "b", "c"} + in1 := []interface{}{1, "a", 2, "b"} + + func1 := func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + } + + a1 := garray.NewSortedStringArrayFrom(s1) + b1 := garray.NewStringArrayFrom(s1) + b2 := garray.NewIntArrayFrom(n3) + b3 := garray.NewArrayFrom(in1) + b4 := garray.NewSortedStringArrayFrom(s1) + b5 := garray.NewSortedIntArrayFrom(n3) + b6 := garray.NewSortedArrayFrom(in1, func1) + + gtest.Assert(a1.Merge(n2).Len(), 6) + gtest.Assert(a1.Merge(n3).Len(), 8) + gtest.Assert(a1.Merge(b1).Len(), 11) + gtest.Assert(a1.Merge(b2).Len(), 13) + gtest.Assert(a1.Merge(b3).Len(), 17) + gtest.Assert(a1.Merge(b4).Len(), 20) + gtest.Assert(a1.Merge(b5).Len(), 22) + gtest.Assert(a1.Merge(b6).Len(), 26) + }) +} + +func TestStringArray_SortFunc(t *testing.T) { + gtest.Case(t, func() { + s1 := []string{"a", "b", "d", "c"} + a1 := garray.NewStringArrayFrom(s1) + func1 := func(v1, v2 string) bool { + return strings.Compare(gconv.String(v1), gconv.String(v2)) < 0 + } + func2 := func(v1, v2 string) bool { + return strings.Compare(gconv.String(v1), gconv.String(v2)) > 0 + } + + a2 := a1.SortFunc(func1) + gtest.Assert(a2, []string{"a", "b", "c", "d"}) + + a3 := a1.SortFunc(func2) + gtest.Assert(a3, []string{"d", "c", "b", "a"}) + }) + +} + +func TestStringArray_LockFunc(t *testing.T) { + gtest.Case(t, func() { + s1 := []string{"a", "b", "c", "d"} + a1 := garray.NewStringArrayFrom(s1) + + ch1 := make(chan int64, 2) + go a1.LockFunc(func(n1 []string) { //互斥锁 + n1[3] = "f" + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 相差大于0.6秒,说明在读取a1.len时,发生了等待。 防止ci抖动,以豪秒为单位 + gtest.AssertGT(t2-t1, 600) + gtest.Assert(a1.Contains("f"), true) + }) +} + +func TestStringArray_RLockFunc(t *testing.T) { + gtest.Case(t, func() { + s1 := []string{"a", "b", "c", "d"} + a1 := garray.NewStringArrayFrom(s1) + + ch1 := make(chan int64, 2) + go a1.RLockFunc(func(n1 []string) { //读锁 + n1[2] = "g" + time.Sleep(1 * time.Second) //暂停一秒 + }) + + go func() { + time.Sleep(10 * time.Millisecond) //故意暂停0.01秒,等另一个goroutine执行锁后,再开始执行. + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + a1.Len() + ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000) + }() + + t1 := <-ch1 + t2 := <-ch1 + // 由于另一个goroutine加的读锁,其它可读,所以ch1的操作间隔是很小的.a.len 操作并没有等待, + // 防止ci抖动,以豪秒为单位 + gtest.AssertLT(t2-t1, 2) + gtest.Assert(a1.Contains("g"), true) + }) +} + +func TestStringArray_Merge(t *testing.T) { + gtest.Case(t, func() { + //n1 := []int{1, 2, 4, 3} + n2 := []int{7, 8, 9} + n3 := []int{3, 6} + + s1 := []string{"a", "b", "c"} + in1 := []interface{}{1, "a", 2, "b"} + + func1 := func(v1, v2 interface{}) int { + return strings.Compare(gconv.String(v1), gconv.String(v2)) + } + + a1 := garray.NewStringArrayFrom(s1) + b1 := garray.NewStringArrayFrom(s1) + b2 := garray.NewIntArrayFrom(n3) + b3 := garray.NewArrayFrom(in1) + b4 := garray.NewSortedStringArrayFrom(s1) + b5 := garray.NewSortedIntArrayFrom(n3) + b6 := garray.NewSortedArrayFrom(in1, func1) + + gtest.Assert(a1.Merge(n2).Len(), 6) + gtest.Assert(a1.Merge(n3).Len(), 8) + gtest.Assert(a1.Merge(b1).Len(), 11) + gtest.Assert(a1.Merge(b2).Len(), 13) + gtest.Assert(a1.Merge(b3).Len(), 17) + gtest.Assert(a1.Merge(b4).Len(), 20) + gtest.Assert(a1.Merge(b5).Len(), 22) + gtest.Assert(a1.Merge(b6).Len(), 26) }) } From 278fd3515fbfeff28fd28835babf5af774ca2ec4 Mon Sep 17 00:00:00 2001 From: jroam Date: Thu, 27 Jun 2019 10:21:49 +0800 Subject: [PATCH 7/7] edit garray of tests --- g/container/garray/garray_z_unit_int_test.go | 12 ++++++------ g/container/garray/garray_z_unit_interface_test.go | 4 ++-- g/container/garray/garray_z_unit_string_test.go | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/g/container/garray/garray_z_unit_int_test.go b/g/container/garray/garray_z_unit_int_test.go index 6cdb7590e..056aca2ac 100644 --- a/g/container/garray/garray_z_unit_int_test.go +++ b/g/container/garray/garray_z_unit_int_test.go @@ -668,7 +668,7 @@ func TestSortedIntArray_LockFunc(t *testing.T) { gtest.Assert(i, n1[i-1]) } n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() { @@ -698,7 +698,7 @@ func TestSortedIntArray_RLockFunc(t *testing.T) { gtest.Assert(i, n1[i-1]) } n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() { @@ -762,7 +762,7 @@ func TestSortedArray_LockFunc(t *testing.T) { ch1 := make(chan int64, 2) go a1.LockFunc(func(n1 []interface{}) { //互斥锁 n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() { @@ -791,7 +791,7 @@ func TestSortedArray_RLockFunc(t *testing.T) { ch1 := make(chan int64, 2) go a1.RLockFunc(func(n1 []interface{}) { //互斥锁 n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() { @@ -871,7 +871,7 @@ func TestIntArray_LockFunc(t *testing.T) { ch1 := make(chan int64, 2) go a1.LockFunc(func(n1 []int) { //互斥锁 n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() { @@ -897,7 +897,7 @@ func TestIntArray_RLockFunc(t *testing.T) { ch1 := make(chan int64, 2) go a1.RLockFunc(func(n1 []int) { //互斥锁 n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() { diff --git a/g/container/garray/garray_z_unit_interface_test.go b/g/container/garray/garray_z_unit_interface_test.go index f4f0fd9a6..92f243ed4 100644 --- a/g/container/garray/garray_z_unit_interface_test.go +++ b/g/container/garray/garray_z_unit_interface_test.go @@ -737,7 +737,7 @@ func TestArray_LockFunc(t *testing.T) { ch1 := make(chan int64, 2) go a1.LockFunc(func(n1 []interface{}) { //互斥锁 n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() { @@ -763,7 +763,7 @@ func TestArray_RLockFunc(t *testing.T) { ch1 := make(chan int64, 2) go a1.RLockFunc(func(n1 []interface{}) { //互斥锁 n1[3] = 7 - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() { diff --git a/g/container/garray/garray_z_unit_string_test.go b/g/container/garray/garray_z_unit_string_test.go index bca25e1eb..7708cf3d8 100644 --- a/g/container/garray/garray_z_unit_string_test.go +++ b/g/container/garray/garray_z_unit_string_test.go @@ -636,7 +636,7 @@ func TestSortedStringArray_LockFunc(t *testing.T) { ch1 := make(chan int64, 2) go a1.LockFunc(func(n1 []string) { //互斥锁 n1[3] = "e" - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() { @@ -662,7 +662,7 @@ func TestSortedStringArray_RLockFunc(t *testing.T) { ch1 := make(chan int64, 2) go a1.RLockFunc(func(n1 []string) { //读锁 n1[3] = "e" - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() { @@ -741,7 +741,7 @@ func TestStringArray_LockFunc(t *testing.T) { ch1 := make(chan int64, 2) go a1.LockFunc(func(n1 []string) { //互斥锁 n1[3] = "f" - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() { @@ -767,7 +767,7 @@ func TestStringArray_RLockFunc(t *testing.T) { ch1 := make(chan int64, 2) go a1.RLockFunc(func(n1 []string) { //读锁 n1[2] = "g" - time.Sleep(1 * time.Second) //暂停一秒 + time.Sleep(3 * time.Second) //暂停一秒 }) go func() {