Files
gf/container/garray/garray_z_unit_normal_str_test.go
hailaz ee24da4e72 refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395)
This pull request standardizes the use of the Go 1.18+ `any` type alias
instead of `interface{}` throughout the codebase. The change improves
code readability and aligns with modern Go best practices. The update
touches many files, including core data structures, code generation
templates, logging utilities, and test data, ensuring consistency across
all usages.

**Type alias migration to `any`:**

* Replaced all instances of `interface{}` with `any` in core data
structures such as `garray` and in generated model structs (e.g.,
`TableUser`, `User1`, `User2`) to modernize type usage.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
* Updated function signatures, method parameters, and return types from
`interface{}` to `any` in various parts of the codebase, including code
generation, service logic, and logging utilities (e.g., `mlog`).
[[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74)
[[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
[[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107)
[[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121)
[[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112)
[[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36)
[[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74)
[[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96)

**Generated code and templates:**

* Adjusted generated files and code generation templates to output `any`
instead of `interface{}` for relevant struct fields and function
signatures, ensuring that new code generation aligns with the updated
convention.
[[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
[[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)

**Container and utility updates:**

* Refactored the `garray` container implementation and related
constructors/methods to use `[]any` instead of `[]interface{}`, along
with corresponding function signatures.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52)
[[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62)
[[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86)
[[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97)
[[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114)
[[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124)
[[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143)
[[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167)

These changes collectively modernize the codebase and prepare it for
future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00

853 lines
22 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright GoFrame Author(https://goframe.org). 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.
// go test *.go
package garray_test
import (
"strings"
"testing"
"time"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/internal/empty"
"github.com/gogf/gf/v2/internal/json"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/v2/util/gconv"
)
func Test_StrArray_Basic(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
expect := []string{"0", "1", "2", "3"}
array := garray.NewStrArrayFrom(expect)
array2 := garray.NewStrArrayFrom(expect, true)
array3 := garray.NewStrArrayFrom([]string{})
t.Assert(array.Slice(), expect)
t.Assert(array.Interfaces(), expect)
array.Set(0, "100")
v, ok := array.Get(0)
t.Assert(v, 100)
t.Assert(ok, true)
v, ok = array3.Get(0)
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.Search("100"), 0)
t.Assert(array.Contains("100"), true)
v, ok = array.Remove(0)
t.Assert(v, 100)
t.Assert(ok, true)
v, ok = array.Remove(-1)
t.Assert(v, "")
t.Assert(ok, false)
v, ok = array.Remove(100000)
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.Contains("100"), false)
array.Append("4")
t.Assert(array.Len(), 4)
array.InsertBefore(0, "100")
array.InsertAfter(0, "200")
t.Assert(array.Slice(), []string{"100", "200", "1", "2", "3", "4"})
array.InsertBefore(5, "300")
array.InsertAfter(6, "400")
t.Assert(array.Slice(), []string{"100", "200", "1", "2", "3", "300", "4", "400"})
t.Assert(array.Clear().Len(), 0)
t.Assert(array2.Slice(), expect)
t.Assert(array3.Search("100"), -1)
err := array.InsertBefore(99, "300")
t.AssertNE(err, nil)
array.InsertAfter(99, "400")
t.AssertNE(err, nil)
})
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom([]string{"0", "1", "2", "3"})
copyArray := array.DeepCopy().(*garray.StrArray)
copyArray.Set(0, "1")
cval, _ := copyArray.Get(0)
val, _ := array.Get(0)
t.AssertNE(cval, val)
})
}
func TestStrArray_ContainsI(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
s := garray.NewStrArray()
t.Assert(s.Contains("A"), false)
s.Append("a", "b", "C")
t.Assert(s.Contains("A"), false)
t.Assert(s.Contains("a"), true)
t.Assert(s.ContainsI("A"), true)
})
}
func TestStrArray_Sort(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
expect1 := []string{"0", "1", "2", "3"}
expect2 := []string{"3", "2", "1", "0"}
array := garray.NewStrArray()
for i := 3; i >= 0; i-- {
array.Append(gconv.String(i))
}
array.Sort()
t.Assert(array.Slice(), expect1)
array.Sort(true)
t.Assert(array.Slice(), expect2)
})
}
func TestStrArray_Unique(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
expect := []string{"1", "1", "2", "2", "3", "3", "2", "2"}
array := garray.NewStrArrayFrom(expect)
t.Assert(array.Unique().Slice(), []string{"1", "2", "3"})
array1 := garray.NewStrArrayFrom([]string{})
t.Assert(array1.Unique().Slice(), []string{})
})
}
func TestStrArray_PushAndPop(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
expect := []string{"0", "1", "2", "3"}
array := garray.NewStrArrayFrom(expect)
t.Assert(array.Slice(), expect)
v, ok := array.PopLeft()
t.Assert(v, "0")
t.Assert(ok, true)
v, ok = array.PopRight()
t.Assert(v, "3")
t.Assert(ok, true)
v, ok = array.PopRand()
t.AssertIN(v, []string{"1", "2"})
t.Assert(ok, true)
v, ok = array.PopRand()
t.AssertIN(v, []string{"1", "2"})
t.Assert(ok, true)
v, ok = array.PopRand()
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.Len(), 0)
array.PushLeft("1").PushRight("2")
t.Assert(array.Slice(), []string{"1", "2"})
})
}
func TestStrArray_PopLeft(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom(g.SliceStr{"1", "2", "3"})
v, ok := array.PopLeft()
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array.Len(), 2)
v, ok = array.PopLeft()
t.Assert(v, 2)
t.Assert(ok, true)
t.Assert(array.Len(), 1)
v, ok = array.PopLeft()
t.Assert(v, 3)
t.Assert(ok, true)
t.Assert(array.Len(), 0)
})
}
func TestStrArray_PopRight(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom(g.SliceStr{"1", "2", "3"})
v, ok := array.PopRight()
t.Assert(v, 3)
t.Assert(ok, true)
t.Assert(array.Len(), 2)
v, ok = array.PopRight()
t.Assert(v, 2)
t.Assert(ok, true)
t.Assert(array.Len(), 1)
v, ok = array.PopRight()
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array.Len(), 0)
})
}
func TestStrArray_PopLefts(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom(g.SliceStr{"1", "2", "3"})
t.Assert(array.PopLefts(2), g.Slice{"1", "2"})
t.Assert(array.Len(), 1)
t.Assert(array.PopLefts(2), g.Slice{"3"})
t.Assert(array.Len(), 0)
})
}
func TestStrArray_PopRights(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom(g.SliceStr{"1", "2", "3"})
t.Assert(array.PopRights(2), g.Slice{"2", "3"})
t.Assert(array.Len(), 1)
t.Assert(array.PopLefts(2), g.Slice{"1"})
t.Assert(array.Len(), 0)
})
}
func TestStrArray_PopLeftsAndPopRights(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArray()
v, ok := array.PopLeft()
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.PopLefts(10), nil)
v, ok = array.PopRight()
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.PopRights(10), nil)
v, ok = array.PopRand()
t.Assert(v, "")
t.Assert(ok, false)
t.Assert(array.PopRands(10), nil)
})
gtest.C(t, func(t *gtest.T) {
value1 := []string{"0", "1", "2", "3", "4", "5", "6"}
value2 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(value1)
array2 := garray.NewStrArrayFrom(value2)
t.Assert(array1.PopLefts(2), []any{"0", "1"})
t.Assert(array1.Slice(), []any{"2", "3", "4", "5", "6"})
t.Assert(array1.PopRights(2), []any{"5", "6"})
t.Assert(array1.Slice(), []any{"2", "3", "4"})
t.Assert(array1.PopRights(20), []any{"2", "3", "4"})
t.Assert(array1.Slice(), []any{})
t.Assert(array2.PopLefts(20), []any{"0", "1", "2", "3", "4", "5", "6"})
t.Assert(array2.Slice(), []any{})
})
}
func TestString_Range(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
value1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(value1)
array2 := garray.NewStrArrayFrom(value1, true)
t.Assert(array1.Range(0, 1), []any{"0"})
t.Assert(array1.Range(1, 2), []any{"1"})
t.Assert(array1.Range(0, 2), []any{"0", "1"})
t.Assert(array1.Range(-1, 10), value1)
t.Assert(array1.Range(10, 1), nil)
t.Assert(array2.Range(0, 1), []any{"0"})
})
}
func TestStrArray_Merge(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a11 := []string{"0", "1", "2", "3"}
a21 := []string{"4", "5", "6", "7"}
array1 := garray.NewStrArrayFrom(a11)
array2 := garray.NewStrArrayFrom(a21)
t.Assert(array1.Merge(array2).Slice(), []string{"0", "1", "2", "3", "4", "5", "6", "7"})
func1 := func(v1, v2 any) int {
if gconv.Int(v1) < gconv.Int(v2) {
return 0
}
return 1
}
s1 := []string{"a", "b", "c", "d"}
s2 := []string{"e", "f"}
i1 := garray.NewIntArrayFrom([]int{1, 2, 3})
i2 := garray.NewArrayFrom([]any{3})
s3 := garray.NewStrArrayFrom([]string{"g", "h"})
s4 := garray.NewSortedArrayFrom([]any{4, 5}, func1)
s5 := garray.NewSortedStrArrayFrom(s2)
s6 := garray.NewSortedIntArrayFrom([]int{1, 2, 3})
a1 := garray.NewStrArrayFrom(s1)
t.Assert(a1.Merge(s2).Len(), 6)
t.Assert(a1.Merge(i1).Len(), 9)
t.Assert(a1.Merge(i2).Len(), 10)
t.Assert(a1.Merge(s3).Len(), 12)
t.Assert(a1.Merge(s4).Len(), 14)
t.Assert(a1.Merge(s5).Len(), 16)
t.Assert(a1.Merge(s6).Len(), 19)
})
}
func TestStrArray_Fill(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0"}
a2 := []string{"0"}
array1 := garray.NewStrArrayFrom(a1)
array2 := garray.NewStrArrayFrom(a2)
t.Assert(array1.Fill(1, 2, "100"), nil)
t.Assert(array1.Slice(), []string{"0", "100", "100"})
t.Assert(array2.Fill(0, 2, "100"), nil)
t.Assert(array2.Slice(), []string{"100", "100"})
t.AssertNE(array2.Fill(-1, 2, "100"), nil)
t.Assert(array2.Len(), 2)
})
}
func TestStrArray_Chunk(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"1", "2", "3", "4", "5"}
array1 := garray.NewStrArrayFrom(a1)
chunks := array1.Chunk(2)
t.Assert(len(chunks), 3)
t.Assert(chunks[0], []string{"1", "2"})
t.Assert(chunks[1], []string{"3", "4"})
t.Assert(chunks[2], []string{"5"})
t.Assert(len(array1.Chunk(0)), 0)
})
gtest.C(t, func(t *gtest.T) {
a1 := []string{"1", "2", "3", "4", "5"}
array1 := garray.NewStrArrayFrom(a1)
chunks := array1.Chunk(3)
t.Assert(len(chunks), 2)
t.Assert(chunks[0], []string{"1", "2", "3"})
t.Assert(chunks[1], []string{"4", "5"})
t.Assert(array1.Chunk(0), nil)
})
gtest.C(t, func(t *gtest.T) {
a1 := []string{"1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
chunks := array1.Chunk(2)
t.Assert(len(chunks), 3)
t.Assert(chunks[0], []string{"1", "2"})
t.Assert(chunks[1], []string{"3", "4"})
t.Assert(chunks[2], []string{"5", "6"})
t.Assert(array1.Chunk(0), nil)
})
gtest.C(t, func(t *gtest.T) {
a1 := []string{"1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
chunks := array1.Chunk(3)
t.Assert(len(chunks), 2)
t.Assert(chunks[0], []string{"1", "2", "3"})
t.Assert(chunks[1], []string{"4", "5", "6"})
t.Assert(array1.Chunk(0), nil)
})
}
func TestStrArray_Pad(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0"}
array1 := garray.NewStrArrayFrom(a1)
t.Assert(array1.Pad(3, "1").Slice(), []string{"0", "1", "1"})
t.Assert(array1.Pad(-4, "1").Slice(), []string{"1", "0", "1", "1"})
t.Assert(array1.Pad(3, "1").Slice(), []string{"1", "0", "1", "1"})
})
}
func TestStrArray_SubSlice(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
array2 := garray.NewStrArrayFrom(a1, true)
t.Assert(array1.SubSlice(0, 2), []string{"0", "1"})
t.Assert(array1.SubSlice(2, 2), []string{"2", "3"})
t.Assert(array1.SubSlice(5, 8), []string{"5", "6"})
t.Assert(array1.SubSlice(8, 2), nil)
t.Assert(array1.SubSlice(1, -2), nil)
t.Assert(array1.SubSlice(-5, 2), []string{"2", "3"})
t.Assert(array1.SubSlice(-10, 1), nil)
t.Assert(array2.SubSlice(0, 2), []string{"0", "1"})
})
}
func TestStrArray_Rand(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
t.Assert(len(array1.Rands(2)), "2")
t.Assert(len(array1.Rands(10)), 10)
t.AssertIN(array1.Rands(1)[0], a1)
v, ok := array1.Rand()
t.Assert(ok, true)
t.AssertIN(v, a1)
array2 := garray.NewStrArrayFrom([]string{})
v, ok = array2.Rand()
t.Assert(ok, false)
t.Assert(v, "")
strArray := array2.Rands(1)
t.AssertNil(strArray)
})
}
func TestStrArray_PopRands(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"a", "b", "c", "d", "e", "f", "g"}
array1 := garray.NewStrArrayFrom(a1)
t.AssertIN(array1.PopRands(1), []string{"a", "b", "c", "d", "e", "f", "g"})
t.AssertIN(array1.PopRands(1), []string{"a", "b", "c", "d", "e", "f", "g"})
t.AssertNI(array1.PopRands(1), array1.Slice())
t.AssertNI(array1.PopRands(1), array1.Slice())
t.Assert(len(array1.PopRands(10)), 3)
})
}
func TestStrArray_Shuffle(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
t.Assert(array1.Shuffle().Len(), 7)
})
}
func TestStrArray_Reverse(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
t.Assert(array1.Reverse().Slice(), []string{"6", "5", "4", "3", "2", "1", "0"})
})
}
func TestStrArray_Join(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
t.Assert(array1.Join("."), `0.1.2.3.4.5.6`)
})
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", `"a"`, `\a`}
array1 := garray.NewStrArrayFrom(a1)
t.Assert(array1.Join("."), `0.1."a".\a`)
})
gtest.C(t, func(t *gtest.T) {
a1 := []string{}
array1 := garray.NewStrArrayFrom(a1)
t.Assert(array1.Join("."), "")
})
}
func TestStrArray_String(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
t.Assert(array1.String(), `["0","1","2","3","4","5","6"]`)
array1 = nil
t.Assert(array1.String(), "")
})
}
func TestNewStrArrayFromCopy(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
a2 := garray.NewStrArrayFromCopy(a1)
a3 := garray.NewStrArrayFromCopy(a1, true)
t.Assert(a2.Contains("1"), true)
t.Assert(a2.Len(), 7)
t.Assert(a2, a3)
})
}
func TestStrArray_SetArray(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
a2 := []string{"a", "b", "c", "d"}
array1 := garray.NewStrArrayFrom(a1)
t.Assert(array1.Contains("2"), true)
t.Assert(array1.Len(), 7)
array1 = array1.SetArray(a2)
t.Assert(array1.Contains("2"), false)
t.Assert(array1.Contains("c"), true)
t.Assert(array1.Len(), 4)
})
}
func TestStrArray_Replace(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
a2 := []string{"a", "b", "c", "d"}
a3 := []string{"o", "p", "q", "x", "y", "z", "w", "r", "v"}
array1 := garray.NewStrArrayFrom(a1)
t.Assert(array1.Contains("2"), true)
t.Assert(array1.Len(), 7)
array1 = array1.Replace(a2)
t.Assert(array1.Contains("2"), false)
t.Assert(array1.Contains("c"), true)
t.Assert(array1.Contains("5"), true)
t.Assert(array1.Len(), 7)
array1 = array1.Replace(a3)
t.Assert(array1.Contains("2"), false)
t.Assert(array1.Contains("c"), false)
t.Assert(array1.Contains("5"), false)
t.Assert(array1.Contains("p"), true)
t.Assert(array1.Contains("r"), false)
t.Assert(array1.Len(), 7)
})
}
func TestStrArray_Sum(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
a2 := []string{"0", "a", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
array2 := garray.NewStrArrayFrom(a2)
t.Assert(array1.Sum(), 21)
t.Assert(array2.Sum(), 18)
})
}
func TestStrArray_PopRand(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
str1, ok := array1.PopRand()
t.Assert(strings.Contains("0,1,2,3,4,5,6", str1), true)
t.Assert(array1.Len(), 6)
t.Assert(ok, true)
})
}
func TestStrArray_Clone(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
array2 := array1.Clone()
t.Assert(array2, array1)
t.Assert(array2.Len(), 7)
})
}
func TestStrArray_CountValues(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "4", "6"}
array1 := garray.NewStrArrayFrom(a1)
m1 := array1.CountValues()
t.Assert(len(m1), 6)
t.Assert(m1["2"], 1)
t.Assert(m1["4"], 2)
})
}
func TestStrArray_Remove(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "a", "c"}
array1 := garray.NewStrArrayFrom(a1)
s1, ok := array1.Remove(1)
t.Assert(s1, "a")
t.Assert(ok, true)
t.Assert(array1.Len(), 4)
s1, ok = array1.Remove(3)
t.Assert(s1, "c")
t.Assert(ok, true)
t.Assert(array1.Len(), 3)
})
}
func TestStrArray_RLockFunc(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
s1 := []string{"a", "b", "c", "d"}
a1 := garray.NewStrArrayFrom(s1, true)
ch1 := make(chan int64, 3)
ch2 := make(chan int64, 1)
// go1
go a1.RLockFunc(func(n1 []string) { // 读锁
time.Sleep(2 * time.Second) // 暂停1秒
n1[2] = "g"
ch2 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000)
})
// go2
go func() {
time.Sleep(100 * time.Millisecond) // 故意暂停0.01秒,等go1执行锁后再开始执行.
ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000)
a1.Len()
ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000)
}()
t1 := <-ch1
t2 := <-ch1
<-ch2 // 等待go1完成
// 防止ci抖动,以豪秒为单位
t.AssertLT(t2-t1, 20) // go1加的读锁所go2读的时候并没有阻塞。
t.Assert(a1.Contains("g"), true)
})
}
func TestStrArray_SortFunc(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
s1 := []string{"a", "d", "c", "b"}
a1 := garray.NewStrArrayFrom(s1)
func1 := func(v1, v2 string) bool {
return v1 < v2
}
a11 := a1.SortFunc(func1)
t.Assert(a11, []string{"a", "b", "c", "d"})
})
}
func TestStrArray_LockFunc(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
s1 := []string{"a", "b", "c", "d"}
a1 := garray.NewStrArrayFrom(s1, true)
ch1 := make(chan int64, 3)
ch2 := make(chan int64, 3)
// go1
go a1.LockFunc(func(n1 []string) { // 读写锁
time.Sleep(2 * time.Second) // 暂停2秒
n1[2] = "g"
ch2 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000)
})
// go2
go func() {
time.Sleep(100 * time.Millisecond) // 故意暂停0.01秒,等go1执行锁后再开始执行.
ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000)
a1.Len()
ch1 <- gconv.Int64(time.Now().UnixNano() / 1000 / 1000)
}()
t1 := <-ch1
t2 := <-ch1
<-ch2 // 等待go1完成
// 防止ci抖动,以豪秒为单位
t.AssertGT(t2-t1, 20) // go1加的读写互斥锁所go2读的时候被阻塞。
t.Assert(a1.Contains("g"), true)
})
}
func TestStrArray_Json(t *testing.T) {
// array pointer
gtest.C(t, func(t *gtest.T) {
s1 := []string{"a", "b", "d", "c"}
a1 := garray.NewStrArrayFrom(s1)
b1, err1 := json.Marshal(a1)
b2, err2 := json.Marshal(s1)
t.Assert(b1, b2)
t.Assert(err1, err2)
a2 := garray.NewStrArray()
err1 = json.UnmarshalUseNumber(b2, &a2)
t.AssertNil(err1)
t.Assert(a2.Slice(), s1)
var a3 garray.StrArray
err := json.UnmarshalUseNumber(b2, &a3)
t.AssertNil(err)
t.Assert(a3.Slice(), s1)
})
// array value
gtest.C(t, func(t *gtest.T) {
s1 := []string{"a", "b", "d", "c"}
a1 := *garray.NewStrArrayFrom(s1)
b1, err1 := json.Marshal(a1)
b2, err2 := json.Marshal(s1)
t.Assert(b1, b2)
t.Assert(err1, err2)
a2 := garray.NewStrArray()
err1 = json.UnmarshalUseNumber(b2, &a2)
t.AssertNil(err1)
t.Assert(a2.Slice(), s1)
var a3 garray.StrArray
err := json.UnmarshalUseNumber(b2, &a3)
t.AssertNil(err)
t.Assert(a3.Slice(), s1)
})
// array pointer
gtest.C(t, func(t *gtest.T) {
type User struct {
Name string
Scores *garray.StrArray
}
data := g.Map{
"Name": "john",
"Scores": []string{"A+", "A", "A"},
}
b, err := json.Marshal(data)
t.AssertNil(err)
user := new(User)
err = json.UnmarshalUseNumber(b, user)
t.AssertNil(err)
t.Assert(user.Name, data["Name"])
t.Assert(user.Scores, data["Scores"])
})
// array value
gtest.C(t, func(t *gtest.T) {
type User struct {
Name string
Scores garray.StrArray
}
data := g.Map{
"Name": "john",
"Scores": []string{"A+", "A", "A"},
}
b, err := json.Marshal(data)
t.AssertNil(err)
user := new(User)
err = json.UnmarshalUseNumber(b, user)
t.AssertNil(err)
t.Assert(user.Name, data["Name"])
t.Assert(user.Scores, data["Scores"])
})
}
func TestStrArray_Iterator(t *testing.T) {
slice := g.SliceStr{"a", "b", "d", "c"}
array := garray.NewStrArrayFrom(slice)
gtest.C(t, func(t *gtest.T) {
array.Iterator(func(k int, v string) bool {
t.Assert(v, slice[k])
return true
})
})
gtest.C(t, func(t *gtest.T) {
array.IteratorAsc(func(k int, v string) bool {
t.Assert(v, slice[k])
return true
})
})
gtest.C(t, func(t *gtest.T) {
array.IteratorDesc(func(k int, v string) bool {
t.Assert(v, slice[k])
return true
})
})
gtest.C(t, func(t *gtest.T) {
index := 0
array.Iterator(func(k int, v string) bool {
index++
return false
})
t.Assert(index, 1)
})
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorAsc(func(k int, v string) bool {
index++
return false
})
t.Assert(index, 1)
})
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorDesc(func(k int, v string) bool {
index++
return false
})
t.Assert(index, 1)
})
}
func TestStrArray_RemoveValue(t *testing.T) {
slice := g.SliceStr{"a", "b", "d", "c"}
array := garray.NewStrArrayFrom(slice)
gtest.C(t, func(t *gtest.T) {
t.Assert(array.RemoveValue("e"), false)
t.Assert(array.RemoveValue("b"), true)
t.Assert(array.RemoveValue("a"), true)
t.Assert(array.RemoveValue("c"), true)
t.Assert(array.RemoveValue("f"), false)
})
}
func TestStrArray_RemoveValues(t *testing.T) {
slice := g.SliceStr{"a", "b", "d", "c"}
array := garray.NewStrArrayFrom(slice)
gtest.C(t, func(t *gtest.T) {
array.RemoveValues("a", "b", "c")
t.Assert(array.Slice(), g.SliceStr{"d"})
})
}
func TestStrArray_UnmarshalValue(t *testing.T) {
type V struct {
Name string
Array *garray.StrArray
}
// JSON
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`["1","2","3"]`),
}, &v)
t.AssertNil(err)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.SliceStr{"1", "2", "3"})
})
// Map
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": g.SliceStr{"1", "2", "3"},
}, &v)
t.AssertNil(err)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.SliceStr{"1", "2", "3"})
})
}
func TestStrArray_Filter(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom(g.SliceStr{"", "1", "2", "0"})
t.Assert(array.Filter(func(index int, value string) bool {
return empty.IsEmpty(value)
}), g.SliceStr{"1", "2", "0"})
})
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom(g.SliceStr{"1", "2"})
t.Assert(array.Filter(func(index int, value string) bool {
return empty.IsEmpty(value)
}), g.SliceStr{"1", "2"})
})
}
func TestStrArray_FilterEmpty(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom(g.SliceStr{"", "1", "2", "0"})
t.Assert(array.FilterEmpty(), g.SliceStr{"1", "2", "0"})
})
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom(g.SliceStr{"1", "2"})
t.Assert(array.FilterEmpty(), g.SliceStr{"1", "2"})
})
}
func TestStrArray_Walk(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom(g.SliceStr{"1", "2"})
t.Assert(array.Walk(func(value string) string {
return "key-" + value
}), g.Slice{"key-1", "key-2"})
})
}