Compare commits

..

59 Commits

Author SHA1 Message Date
992522342c version/readme update 2020-03-30 23:56:26 +08:00
040898cdc3 improve unit testing case for package gmutex 2020-03-30 22:55:03 +08:00
343126ef22 fix usage for garray.PopRand 2020-03-30 20:56:00 +08:00
05760d1eac fix usage for garray.PopRand 2020-03-30 20:47:50 +08:00
c10f73f1f7 add zero time.Time filtering for omitempty feature of gdb.Model 2020-03-30 20:44:36 +08:00
7e0fa8e0cd improve package garray 2020-03-30 20:31:47 +08:00
6fe6218505 README updates 2020-03-29 20:23:10 +08:00
6059782de8 add unit testing case of basic auth for ghttp.Client; remove intlog for New function of package gspath 2020-03-29 19:36:49 +08:00
4844eea0ab add convenience function g.Client for ghttp.Client 2020-03-29 09:52:37 +08:00
8ecd62d3de add example for package gres 2020-03-28 21:32:29 +08:00
4c610b4f58 improve session storage file for ghttp.Server 2020-03-28 20:02:57 +08:00
1932c4ec44 Merge pull request #575 from wenzi1/master
Fix the bug of MSSQL paging
2020-03-28 19:59:31 +08:00
bd2e51ddca improve unit testing case for package glog 2020-03-28 00:47:34 +08:00
ddcb7121c1 improve temporary path producing from gfile.Join to gfile.TempDir 2020-03-28 00:41:12 +08:00
f1f575fd5c improve package gins/gfile/intlog 2020-03-28 00:37:23 +08:00
99adb7cdc4 comment update 2020-03-26 23:48:21 +08:00
6b7ea97777 improve quote handling of table string for package gdb; improve rotation feature for package glog 2020-03-26 22:25:43 +08:00
495b5758ec improve quote handling of table string for package gdb; improve rotation feature for package glog 2020-03-26 22:22:27 +08:00
ba56eb87b1 improve rotation feature for package glog 2020-03-26 20:58:57 +08:00
4258a3bbc9 improve StrToSize function for package gfile 2020-03-26 15:54:57 +08:00
4912331ddc improve mtime feature for gfile; improve rotation feature for glog 2020-03-26 09:29:36 +08:00
e87b7ecf5d improve unit testing case for package gfpool 2020-03-26 08:52:50 +08:00
23bce7bde6 reduce the goroutine count for unit testing cases of package gfpool/glog 2020-03-25 23:49:33 +08:00
926b664615 improve package garray for crossing border handling; improve rotation feature for package glog 2020-03-25 23:36:56 +08:00
fa8257c85b improve ghttp.Client 2020-03-25 17:13:05 +08:00
abb9c88c23 improve ghttp.Client 2020-03-25 15:17:18 +08:00
f89976cad5 improve ghttp.Client 2020-03-25 15:09:13 +08:00
0389778725 improve package glog for file lock 2020-03-25 00:03:52 +08:00
3c36285126 improve Model.Data function for package gdb 2020-03-24 20:58:11 +08:00
75054ee109 fix issue in rebinding feature for grou router of ghttp.Server 2020-03-24 19:48:10 +08:00
8447b1a42b add function LevelStr/StackWithFilter functions for package glog 2020-03-24 00:05:11 +08:00
e5265a1c46 add level string feature for package glog 2020-03-23 22:40:44 +08:00
6e8ef8d0b0 add level string feature for package glog 2020-03-23 22:36:06 +08:00
75c081afc9 fix issue of char '/' in URL.Path handling of ghttp.Server 2020-03-23 20:57:34 +08:00
060fd9eaba improve comment for package gdb 2020-03-23 20:44:20 +08:00
63e5a60344 improve package gdb 2020-03-22 23:26:15 +08:00
75dc1d82c1 example names change 2020-03-22 12:49:46 +08:00
a5e048eb5f example name changes 2020-03-22 12:34:12 +08:00
65bc1d5eb8 comment update for package gjson 2020-03-22 09:24:45 +08:00
bfa64705b5 update comment for package gsession 2020-03-22 00:15:59 +08:00
17aea8d7d4 improve unit testing cases by changing creating testdata path using gdebug.TestdataPath function 2020-03-21 23:47:33 +08:00
a6a01fd7f2 improve template cache for ParseContent function of package gview 2020-03-21 23:42:34 +08:00
41a9e91b4c improve example for package gpage 2020-03-21 23:13:31 +08:00
e2c1e11f95 improve package gjson 2020-03-21 21:32:02 +08:00
c2966817ce improve function gdebug.TestDataPath and update all usage codes 2020-03-21 19:41:05 +08:00
16958413bb improve autoencode feature for package gview 2020-03-21 19:31:58 +08:00
c0a0913d4b add more unit testing case for template feature of ghttp.Server 2020-03-21 13:45:33 +08:00
6d47810782 improve context feature for ghttp.Request; improve comment for package gjson 2020-03-21 13:32:43 +08:00
7a9ea2e546 improve context feature for ghttp.Request 2020-03-20 23:22:32 +08:00
7881b2dee4 improve unit testing cases 2020-03-20 22:34:56 +08:00
5f223ef049 Merge pull request #4 from gogf/master
update
2020-03-20 10:06:50 +08:00
e57942b374 improve unit testing cases 2020-03-20 08:56:17 +08:00
f18e6f078c improve unit testing cases 2020-03-20 08:49:40 +08:00
f667cbc2a2 Fix the bug of MSSQL paging 2020-03-20 00:33:20 +08:00
07e65c14a9 improve unit testing cases 2020-03-19 23:53:03 +08:00
0b6d04485e improve unit testing cases 2020-03-19 22:56:12 +08:00
36401a063d improve gutil.Dump, improve sqlite file searching when opening db file 2020-03-19 13:38:42 +08:00
849e7370d1 improve gutil.Dump, improve sqlite file searching when opening db file 2020-03-19 11:37:31 +08:00
6174097a07 Merge pull request #3 from gogf/master
update
2020-03-17 22:11:51 +08:00
324 changed files with 16841 additions and 13510 deletions

View File

@ -8,112 +8,72 @@ package driver
import (
"database/sql"
"fmt"
"github.com/gogf/gf/database/gdb"
"github.com/gogf/gf/internal/intlog"
"github.com/gogf/gf/text/gstr"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/gtime"
)
// MyDriver is a custom database driver, which is used for testing only.
// For simplifying the unit testing case purpose, MyDriver struct inherits the mysql driver
// gdb.DriverMysql and overwrites its functions DoQuery and DoExec.
// So if there's any sql execution, it goes through MyDriver.DoQuery/MyDriver.DoExec firstly
// and then gdb.DriverMysql.DoQuery/gdb.DriverMysql.DoExec.
// You can call it sql "HOOK" or "HiJack" as your will.
type MyDriver struct {
*gdb.Core
*gdb.DriverMysql
}
// Open creates and returns a underlying sql.DB object for mysql.
func (d *MyDriver) Open(config *gdb.ConfigNode) (*sql.DB, error) {
var source string
if config.LinkInfo != "" {
source = config.LinkInfo
} else {
source = fmt.Sprintf(
"%s:%s@tcp(%s:%s)/%s?charset=%s&multiStatements=true&parseTime=true&loc=Local",
config.User, config.Pass, config.Host, config.Port, config.Name, config.Charset,
)
}
intlog.Printf("Open: %s", source)
if db, err := sql.Open("mysql", source); err == nil {
return db, nil
} else {
return nil, err
var (
// customDriverName is my driver name, which is used for registering.
customDriverName = "MyDriver"
)
func init() {
// It here registers my custom driver in package initialization function "init".
// You can later use this type in the database configuration.
if err := gdb.Register(customDriverName, &MyDriver{}); err != nil {
panic(err)
}
}
// getChars returns the security char for this type of database.
func (d *MyDriver) GetChars() (charLeft string, charRight string) {
return "`", "`"
// New creates and returns a database object for mysql.
// It implements the interface of gdb.Driver for extra database driver installation.
func (d *MyDriver) New(core *gdb.Core, node *gdb.ConfigNode) (gdb.DB, error) {
return &MyDriver{
&gdb.DriverMysql{
Core: core,
},
}, nil
}
// handleSqlBeforeExec handles the sql before posts it to database.
func (d *MyDriver) HandleSqlBeforeExec(sql string) string {
return sql
}
// Tables retrieves and returns the tables of current schema.
func (d *MyDriver) Tables(schema ...string) (tables []string, err error) {
var result gdb.Result
link, err := d.DB.GetSlave(schema...)
if err != nil {
return nil, err
}
result, err = d.DB.DoGetAll(link, `SHOW TABLES`)
if err != nil {
return
}
for _, m := range result {
for _, v := range m {
tables = append(tables, v.String())
}
// DoQuery commits the sql string and its arguments to underlying driver
// through given link object and returns the execution result.
func (d *MyDriver) DoQuery(link gdb.Link, sql string, args ...interface{}) (rows *sql.Rows, err error) {
tsMilli := gtime.TimestampMilli()
rows, err = d.DriverMysql.DoQuery(link, sql, args...)
if _, err := d.DriverMysql.InsertIgnore("monitor", g.Map{
"sql": gdb.FormatSqlWithArgs(sql, args),
"cost": gtime.TimestampMilli() - tsMilli,
"time": gtime.Now(),
"error": err.Error(),
}); err != nil {
panic(err)
}
return
}
// gdb.TableFields retrieves and returns the fields information of specified table of current schema.
//
// Note that it returns a map containing the field name and its corresponding fields.
// As a map is unsorted, the gdb.TableField struct has a "Index" field marks its sequence in the fields.
//
// It's using cache feature to enhance the performance, which is never expired util the process restarts.
func (d *MyDriver) TableFields(table string, schema ...string) (fields map[string]*gdb.TableField, err error) {
table = gstr.Trim(table)
if gstr.Contains(table, " ") {
panic("function gdb.TableFields supports only single table operations")
}
checkSchema := d.DB.GetSchema()
if len(schema) > 0 && schema[0] != "" {
checkSchema = schema[0]
}
v := d.DB.GetCache().GetOrSetFunc(
fmt.Sprintf(`mysql_table_fields_%s_%s`, table, checkSchema),
func() interface{} {
var result gdb.Result
var link *sql.DB
link, err = d.DB.GetSlave(checkSchema)
if err != nil {
return nil
}
result, err = d.DB.DoGetAll(
link,
fmt.Sprintf(`SHOW FULL COLUMNS FROM %s`, d.DB.QuoteWord(table)),
)
if err != nil {
return nil
}
fields = make(map[string]*gdb.TableField)
for i, m := range result {
fields[m["Field"].String()] = &gdb.TableField{
Index: i,
Name: m["Field"].String(),
Type: m["Type"].String(),
Null: m["Null"].Bool(),
Key: m["Key"].String(),
Default: m["Default"].Val(),
Extra: m["Extra"].String(),
Comment: m["Comment"].String(),
}
}
return fields
}, 0)
if err == nil {
fields = v.(map[string]*gdb.TableField)
// DoExec commits the query string and its arguments to underlying driver
// through given link object and returns the execution result.
func (d *MyDriver) DoExec(link gdb.Link, sql string, args ...interface{}) (result sql.Result, err error) {
tsMilli := gtime.TimestampMilli()
result, err = d.DriverMysql.DoExec(link, sql, args...)
if _, err := d.DriverMysql.InsertIgnore("monitor", g.Map{
"sql": gdb.FormatSqlWithArgs(sql, args),
"cost": gtime.TimestampMilli() - tsMilli,
"time": gtime.Now(),
"error": err.Error(),
}); err != nil {
panic(err)
}
return
}

View File

@ -8,7 +8,6 @@ import (
func main() {
s := ghttp.GetServer()
s.BindHandler("/", func(r *ghttp.Request) {
r.Response.Write("Hello World")
r.Response.WriteTpl("index.tpl", g.Map{
"title": "Test",
"name": "John",

View File

@ -0,0 +1,11 @@
package main
import (
"github.com/gogf/gf/os/glog"
)
func main() {
l := glog.New()
l.SetLevelPrefix(glog.LEVEL_DEBU, "debug")
l.Debug("test")
}

View File

@ -1,16 +0,0 @@
package main
import (
"github.com/gogf/gf/os/gres"
_ "github.com/gogf/gf/os/gres/testdata"
)
func main() {
gres.Dump()
//file := gres.Get("www")
//fmt.Println(file.Open())
//g.Dump(gres.ScanDir("/root/image", "*"))
//g.Dump(gres.Scan("/root/image/", "*", true))
//g.Dump(gres.Scan("/template", "*"))
//g.Dump(gres.Scan("/template/layout2", "*.html", true))
}

View File

@ -0,0 +1,20 @@
package main
import (
_ "github.com/gogf/gf/os/gres/testdata/example/boot"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
s.Group("/", func(group *ghttp.RouterGroup) {
group.GET("/template", func(r *ghttp.Request) {
r.Response.WriteTplDefault(g.Map{
"name": "GoFrame",
})
})
})
s.Run()
}

View File

@ -7,6 +7,12 @@
default = "127.0.0.1:6379,0"
cache = "127.0.0.1:6379,1"
# Logger.
[logger]
Path = "/tmp/log/gf-app"
Level = "all"
Stdout = true
[viewer]
delimiters = ["${", "}"]
autoencode = true

View File

@ -1,35 +1,21 @@
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/os/glog"
"github.com/gogf/gf/os/gtime"
"github.com/gogf/gf/os/gtimer"
"time"
"fmt"
)
func GetList() {
START:
for {
res, err := g.Redis().DoVar("RPOP", "mill")
if err != nil {
glog.Debug("Rpop:", err)
break
}
glog.Debug(res)
if res.IsEmpty() {
glog.Debug("nil")
continue START
}
interval := 50 * time.Second
gtimer.AddOnce(interval, func() {
glog.Debug("end------:", res, gtime.Now().Format("Y-m-d H:i:s"))
})
}
func Test() (int, int) {
return 1, 1
}
func Assert(v1, v2, v3 interface{}) {
fmt.Println(v1)
}
func F(v ...interface{}) []interface{} {
return v
}
func main() {
g.Redis().SetMaxActive(2)
//g.Redis().SetMaxIdle(100)
GetList()
Assert(F(Test()), 2, 3)
}

View File

@ -7,7 +7,7 @@ import (
)
func main() {
s := ghttp.GetServer()
s := g.Server()
s.BindHandler("/page/demo", func(r *ghttp.Request) {
page := r.GetPage(100, 10)
buffer, _ := gview.ParseContent(`

View File

@ -7,7 +7,7 @@ import (
)
func main() {
s := ghttp.GetServer()
s := g.Server()
s.BindHandler("/page/ajax", func(r *ghttp.Request) {
page := r.GetPage(100, 10)
page.AjaxActionName = "DoAjax"

View File

@ -8,7 +8,7 @@ import (
"github.com/gogf/gf/util/gpage"
)
// 分页标签使用li标签包裹
// wrapContent wraps each of the page tag with html li and ul.
func wrapContent(page *gpage.Page) string {
content := page.GetContent(4)
content = gstr.ReplaceByMap(content, map[string]string{
@ -21,7 +21,7 @@ func wrapContent(page *gpage.Page) string {
}
func main() {
s := ghttp.GetServer()
s := g.Server()
s.BindHandler("/page/custom1/*page", func(r *ghttp.Request) {
page := r.GetPage(100, 10)
content := wrapContent(page)

View File

@ -7,7 +7,7 @@ import (
"github.com/gogf/gf/util/gpage"
)
// 自定义分页名称
// pageContent customizes the page tag name.
func pageContent(page *gpage.Page) string {
page.NextPageTag = "NextPage"
page.PrevPageTag = "PrevPage"
@ -22,7 +22,7 @@ func pageContent(page *gpage.Page) string {
}
func main() {
s := ghttp.GetServer()
s := g.Server()
s.BindHandler("/page/custom2/*page", func(r *ghttp.Request) {
page := r.GetPage(100, 10)
buffer, _ := gview.ParseContent(`

View File

@ -1,8 +1,6 @@
language: go
go:
- "1.11.x"
- "1.12.x"
- "1.13.x"
- "1.14.x"

View File

@ -68,6 +68,7 @@ We currently accept donation by Alipay/WechatPay, please note your github/gitee
|金毛|alipay|¥100.00|
|1*1x|wechat|¥100.00|
|[ywanbing](https://github.com/ywanbing)|wechat|¥66.66|
|[侯哥](http://www.macnie.com)|wechat|¥10.00|
<img src="https://goframe.org/images/donate.png"/>

View File

@ -28,7 +28,7 @@ require github.com/gogf/gf latest
# Limitation
```
golang version >= 1.11
golang version >= 1.13
```
# Documentation

View File

@ -41,7 +41,7 @@ require github.com/gogf/gf latest
# 限制
```shell
golang版本 >= 1.11
golang版本 >= 1.13
```
# 架构

View File

@ -1,3 +1,351 @@
# `v1.12.1` (2020-03-31)
大家好啊!久等啦!
由于自从上次版本的发布以来,越来越多小伙伴加入了`GF`的大家庭,并提供了许多不错的建议和反馈,这次版本对其中大部分反馈进行了处理,包括大部分的改进建议和部分新特性,因此这次的版本发布时隔了两个多月。`GF`非常注重代码质量以及可持续维护性,这次版本也进一步对框架大部分模块的示例、注释和单元测试用例进行了完善,目前单元测试用例数量约为`1991`例,代码覆盖率为`71%`,覆盖了所有模块的绝大部分主要功能。
`GF`框架提供了比较常用、高质量的基础开发模块,轻量级、模块化、高性能,推荐大家阅读框架源码了解更多细节。本次发布有个别的不兼容升级,往往批量替换即可,以下`change log`比较完善,建议升级前仔细阅读。
本次发布即意味下一版本开发计划的开启欢迎更多小伙伴参与开源贡献https://github.com/gogf/gf/projects/8
感谢大家支持Enjoy your `GF`
# GoFrame
`GF(Go Frame)`是一款模块化、高性能、生产级的Go基础开发框架。实现了比较完善的基础设施建设以及开发工具链提供了常用的基础开发模块缓存、日志、队列、数组、集合、容器、定时器、命令行、内存锁、对象池、配置管理、资源管理、数据校验、数据编码、定时任务、数据库ORM、TCP/UDP组件、进程管理/通信等等。并提供了Web服务开发的系列核心组件Router、Cookie、Session、Middleware、服务注册、模板引擎等等支持热重启、热更新、域名绑定、TLS/HTTPS、Rewrite等特性。
## 特点
* 模块化、松耦合设计;
* 模块丰富,开箱即用;
* 简便易用,易于维护;
* 社区活跃,大牛谦逊低调脾气好;
* 高代码质量、高单元测试覆盖率;
* 详尽的开发文档及示例;
* 完善的本地中文化支持;
* 更适合企业及团队使用;
## 地址
- 官网https://goframe.org
- 主库https://github.com/gogf/gf
- 码云https://gitee.com/johng/gf
# Change Log
从`GF v1.12`版本开始,框架要求的最低`Golang`运行版本为`v1.13`,由于`Golang`新版本都是向后兼容的,因此推荐大家更新使用`Golang`新版本https://golang.google.cn/dl/
> 本次版本也新增了`Swagger`的工具及插件支持,另行独立发布。
## `tool chain`
1. `gen model`命令新增对`pgsql/mssql/sqlite/oracle`的模型生成支持。
1. `gen model`命令生成模型新增公开包变量`Columns`用于获得表的字段名称。
## `net`
1. `ghttp`
- 注意:从该版本开始,`Server`默认关闭了平滑重启特性。开发者可以通过相应的配置选项打开。
- 改进`Client.Get`方法,增加可选的请求参数。
- 新增`Client`链式操作方法:`Header`, `HeaderRaw`, `Cookie`, `ContentType`, `ContentJson`, `ContentXml`, `Timeout`, `BasicAuth`, `Ctx`https://goframe.org/net/ghttp/client/chain
- 新增`Request.GetCtx/GetCtxVar/SetCtxVar/Context`上下文变量管理方法,用于请求内部的上下文变量特性:
- 自定义变量https://goframe.org/net/ghttp/request/custom
- 上下文变量https://goframe.org/net/ghttp/request/context
- 新增`Request.GetUploadFile/GetUploadFiles`方法,以及`UploadFile`类型极大简化文件上传处理逻辑https://goframe.org/net/ghttp/client/demo/upload
- 新增`Request.GetPage`方法,用于便捷地获得分页对象:
- 基本介绍https://goframe.org/util/gpage/index
- 动态分页https://goframe.org/util/gpage/dynamic
- 静态分页https://goframe.org/util/gpage/static
- Ajax分页https://goframe.org/util/gpage/ajax
- URL模板https://goframe.org/util/gpage/template
- 自定义分页https://goframe.org/util/gpage/custom
- 改进`Response.Redirect*`方法增加自定义的跳转HTTP状态码参数。
- 改进`CORS`特性,完善跨域功能处理,并完全遵守`W3C`关于`OPTIONS`请求方法的规范约定https://goframe.org/net/ghttp/cors
- 模板视图对象增加`Request`内置变量,用于模板获得请求参数。由于`GF`框架的模板引擎采用两级缓存设计,减少`IO`开销的同时提升了执行效率,即使增加了大量的内置变量以及内置方法,经过大规模的性能测试,性能比其他`WebServer`库相同逻辑下高出`50% - 200%`的效率。
- 新增`Server`实验性的`Plugin`特性。
- 改进`Server`底层路由存储、检索逻辑,优化代码,提升效率。
- 改进分组路由注册的源码位置记录功能,当路由注册冲突时能够精准定位及提示重复路由源码位置。
- 改进`Server`日志处理。
- 完善单元测试。
## `database`
1. `gdb`
- 代码重构改进,增加`Driver`驱动接口设计,方便开发者自定义驱动实现。新增`Register`包方法用于开发者注册自定义的数据库类型驱动https://goframe.org/database/gdb/driver
- 新增`GetArray`接口及实现用于获取指定字段列的数据构造成数组返回https://goframe.org/database/gdb/chaining/select
- 新增`InsertIgnore`接口及实现,用于写入时忽略写入冲突,仅对`mysql`数据库类型有效https://goframe.org/database/gdb/chaining/insert-save
- 新增`Schema`接口及实现用于动态切换并获取指定名称的数据库对象https://goframe.org/database/gdb/chaining/schema
- 新增`FieldsStr/FieldsExStr`模型方法用于获取表字段并构造成字符串返回hhttps://goframe.org/database/gdb/chaining/fields-retrieve
- 新增`LockUpdate/LockShared`模型链式操作方法用于实现悲观锁操作https://goframe.org/database/gdb/chaining/lock
- 改进`Where/Data`方法对更新参数输入方式的支持,提高灵活性:
- https://goframe.org/database/gdb/chaining/select
- https://goframe.org/database/gdb/chaining/update-delete
- 查询结果对象`Result`新增`Array`方法用于获得指定字段的数值构造成数组返回https://goframe.org/database/gdb/result
- 改进`OmitEmpty`方法对`Data`输入参数的过滤,当给定的`Data`参数为空时间对象时,将会被过滤。
- 增加默认的数据库连接池参数:`MaxIdleConns=10`。
- 其他一些改进。
- 完善单元测试。
1. `gredis`
- 增加/修改默认的数据库连接池参数:`MaxIdle=10`, `IdleTimeout=10s`, `MaxConnLifetime=30s`, `Wait=true`。
- 完善单元测试。
## `container`
1. 所有容器对象新增`UnmarshalValue(interface{}) error`接口方法实现,用于`gconv`转换时根据任意类型变量创建/设置对象内容,`GF`框架的所有容器对象均实现了该接口。
1. `garray`
- 新增`RemoveValue`方法,用于根据数值检索并删除元素项。
- 新增`FilterNil`方法,用于遍历并删除数组中的`nil`元素项。
- 新增`FilterEmpty`方法,用于遍历并删除数组中的空值元素项,空值包括:`0, nil, false, "", len(slice/map/chan) == 0`。
- 改进`Set/Fill/InsertBefore/InsertAfter`方法严谨性,将原有的链式操作返回值对象修改为`error`返回值。
- 改进`Get/Remove/PopRand/PopLeft/PopRight/Rand`方法严谨性,增加`found`的`bool`返回值,标识当前方法是否有数据返回,当空数组或者操作越界时`found`返回值为`false`。
- 改变`Rands`方法原有逻辑,保证按照给定大小返回随机数组。
- 完善单元测试。
1. `gpool`
- 调整缓存池过期时间参数类型,旧版本为`int`类型表示毫秒,新版本为`time.Duration`类型使得时间控制更灵活。
- 内部代码优化,性能改进。
- 完善单元测试。
- 完善注释。
## `os`
1. `glog`
- 增加`Rotation`日志滚动切分特性,新增按照文件大小或过期时间进行日志切分,并支持切分文件数量限制、对日志文件进行自动压缩、可自定义压缩级别(`1-9`、支持对切分文件过期时间清理https://goframe.org/os/glog/rotate
- 新增`LevelPrefixes`特性支持对日志级别的前缀名称进行自定义https://goframe.org/os/glog/level
- 新增`SetLevelStr`方法,并增加按照字符串进行日志级别配置的特性:
- https://goframe.org/os/glog/level
- https://goframe.org/os/glog/config
- 新增`SetDefaultLogger`包方法,用于设置全局默认的`Logger`对象。
1. `gres`
1. 改进资源内容编码设计,采用新的压缩算法,减少资源文件大小,例如原本`15MB`的网站静态资源文件(`css/js/html`等),资源文件打包后约为`4MB`左右https://goframe.org/os/gres/index
1. 注意:该改进与旧版本无法兼容,需要重新打包原有的资源文件。
1. 完善单元测试。
1. `gcfg`
- 去掉配置对象属性的原子并发安全控制,改为普通变量类型。由于配置管理是最常用模块之一,因此确保高效的设计及方法实现。
- 单例对象做较大调整:为方便多文件场景下的配置文件调用,简便使用并提高开发效率,因此当给定的单例名称对应的`toml`配置文件在配置目录中存在时,将自动设置该单例对象的默认配置文件为该文件。例如:`g.Cfg("redis")`获取到的单例对象将会默认去检索并设置默认的配置文件为`redis.toml`,当该文件不存在时,则使用默认的配置文件(`config.toml`https://goframe.org/net/ghttp/config
- 完善单元测试。
1. `gview`
- 新增`concat`内置字符串拼接方法https://goframe.org/os/gview/function/buildin
- 完善单元测试。
1. `gfile`
- 改进`SelfPath`获取当前执行文件路径方法,提高执行效率。
- 改进`Join`文件路径连接方法,防止多余的路径连接符号。
- 改建`GetContents`文件内容获取方法执行效率,降低内存占用。
- 新增`StrToSize`方法,用于将大小字符串转换为字节数字,大小字符串例如`10m`, `5KB`, `1.25Gib`等。
- 新增`ReadLines/ReadByteLines`方法,用于按行读取指定文件内容,并给定读取回调函数。
- 完善单元测试。
1. `gtime`
- 改进`gtime.Time`对象实现,统一字符串打印时间格式为`Y-m-d H:i:s`,如:`2020-01-01 12:00:00`。
1. `gcmd`
- 命令行解析方法增加`strict`参数,用于设置当前解析是否严格解析,严格解析下如果给定了非法的选项,将会停止解析并返回错误。默认情况下为非严格解析。
1. `genv`
- 改进`Remove`删除环境变量键值对方法,增加对多个键值对环境变量的删除。
1. `gfpool`
- 改进代码实现,提高效率。
- 完善单元测试。
1. `gfsnotify`
- 改进包初始化方法,当系统原因引起默认`Watcher`对象创建失败时,直接`panic`。
1. `gproc`
- 改进`SearchBinaryPath`方法。
- 改进`Process.Kill`方法在`windows`及`*niux`平台下不同表现的处理。
## `encoding`
1. `gjson`
- 代码改进、完善注释、新增大量代码示例。
- 文档更新:
- 基本介绍https://goframe.org/encoding/gjson/index
- 对象创建https://goframe.org/encoding/gjson/object
- 层级访问https://goframe.org/encoding/gjson/pattern
- Struct转换https://goframe.org/encoding/gjson/conversion-struct
- 动态创建修改https://goframe.org/encoding/gjson/dataset
- 数据格式转换https://goframe.org/encoding/gjson/conversion-format
## `frame`
1. `g`
- 新增`IsNil`方法,用于判断当前给定的变量是否为`nil`,该方法有可能会使用到反射来实现判断。
- 新增`IsEmpty`方法,用于判断当前给定的变量是否为`空`,该方法优先使用断言判断但有可能会使用到反射来实现判断。空值包括:`0, nil, false, "", len(slice/map/chan) == 0`。
- 标记废弃`SetServerGraceful`方法,转而统一交给`Server`的配置来管理。
1. `gins`
- 改进代码结构,方便维护。
- 改进、完善单元测试。
1. `gmvc`
- 新增`M`类型,为`*gdb.Model`的别名简称,用于工具链自动生成模型中的`M`属性。
## `text`
1. `gstr`
- 新增`HasPrefix/HasSuffix`方法。
- 新增`OctStr`方法,用于将八进制字符串转换为其对应的`unicode`字符串,例如转换为中文。常用于`gRPC`底层通信编码中。
- 完善单元测试。
## `debug`
1. `gdebug`
- 改进代码结构,方便维护。
- 新增`TestDataPath`方法,用于当前包单元测试中获得当前包中`testdata`目录的绝对路径。
## `util`
1. `gconv`
- 改进`String`字符串转换方法,增加对`time.Time/*time.Time/gtime.Time`类型的内置支持。
- 改进`Map/Struct`转换方法,增加对一些特殊场景的细节处理。经过大规模的使用,大量的反馈改进,不断完善了细节。
- 改进`Struct`转换方法,增加对`UnmarshalValue(interface{}) error`接口的支持。
- 完善单元测试。
1. `grand`
- 注意:不兼容调整,原有的`Str`方法更名为`S`方法,用以获取指定长度的随机字符串、数字,并增加`symbol`参数,指定是否可以随机返回特殊可见字符。
- 新增`Str`方法,用于从指定的字符串字符中随机获取指定长度的字符串。该方法同时支持`unicode`字符串例如中文https://goframe.org/util/grand/index
- 新增`Symbols`方法用于随机返回指定场孤独的特殊可见字符https://goframe.org/util/grand/index
- 完善单元测试。
1. `gvalid`
- 长度校验规则增加对`unicode`字符串的支持,例如:中文。
# Bug Fix
1. 修复`Server`的视图对象配置失效问题。
1. 修复`Server`中间件在中间件`panic`情况下,忽略`Middleware.Next`方法控制,导致鉴权中间件失效的问题。
1. 修复`gudp.Server`在请求包大小超过`64bytes`时的断包问题,并调整默认缓冲区大小为`1024byte`,开发者可自定义缓冲区大小。
1. 修复`gfile.MTimeMillisecond`方法返回错误的文件修改毫秒时间戳。
1. 修复`gconv.Int64`对负数转换的支持。
1. 其他一些修复。
1. 详见https://github.com/gogf/gf/issues?q=label%3Abug
# `v1.11.2` (2020-01-14)
`GF(Go Frame)` https://goframe.org 是一款模块化、高性能、生产级的Go基础开发框架。实现了比较完善的基础设施建设包括常用的核心开发组件 如:缓存、日志、文件、时间、队列、数组、集合、字符串、定时器、命令行、文件锁、内存锁、对象池、连接池、资源管理、数据校验、数据编码、文件监控、 定时任务、数据库ORM、TCP/UDP组件、进程管理/通信、并发安全容器等等。 并提供了Web服务开发的系列核心组件Router、Cookie、Session、Middleware、服务注册、配置管理、模板引擎等等 支持热重启、热更新、多域名、多端口、多服务、HTTPS、Rewrite等特性。
`GF`有着丰富的基础模块、完善的工具链、详尽的开发文档。开源近两年以来,`GF`得到越来越多小伙伴的肯定和支持从寂寂无名到现在被广泛应用于微服务、物联网、区块链、电商系统、银行系统等企业级的生产项目中经历了百万级、千万级项目的考验2019年度被码云`gitee`评选为`GVP`最有价值开源项目。`GF`正在快速地成长中目前保持着1-2个月迭代版本的发布规律社区活跃欢迎加入`GF`大家庭。
最后祝大家2020新年快乐鼠年大吉
## 新特性
1. 新年新气象官网文档大量更新https://goframe.org/index
1. `GF`工具链更新https://goframe.org/toolchain/cli
- 新增`gf run`热编译运行命令;
- 新增`gf docker` Docker镜像编译命令
- 新增`gf gen model` 强大的模型自动生成命令;
- `gf build`命令增加对配置文件配置支持;
- 大量命令行工具改进工作;
- 新增自动代理设置特性;
1. 数据库`ORM`新特性:
- 增加`prefix`数据表前缀支持https://goframe.org/database/gdb/config
- 新增`Schema`数据库对象并改进数据库切换特性https://goframe.org/database/gdb/chaining/schema
- 新增`WherePri`方法用于自动识别主键的条件方法https://goframe.org/database/gdb/chaining/select
- 文档及示例大量更新覆盖95%以上的功能特性;
## 功能改进
### `container`
1. `garray`
- 新增`New*ArrayRange`方法,用于初始化创建指定数值范围的数组。
- 新增`Iterator*`方法,用于数组项元素回调遍历。
- 完善单元测试。
1. `gvar`
- 改进`MapStrStr`、`MapStrStrDeep`方法实现。
### `net`
1. `ghttp`
- 改进HTTP客户端增加对提交参数的自动`Content-Type`识别功能。
- `Request`对象增加`Parse`方法,用于快捷的对象转换即参数校验。
- `Request.GetPost*`方法全部标记为`deprecated`,统一客户端参数提交方式为`QueryString`, `Form`, `Body`。
- 去掉`Response`模板解析时的`Get`/`Post`内置变量,新增`Query`, `Form`, `Request`内置变量https://goframe.org/net/ghttp/response/template
- 改进`Response.WriteJson*`及`Response.WriteXml*`方法,增加对`string`, `[]byte`类型参数的支持。
- `Server`新增`GetRouterArray`方法,用于向应用层暴露并获取`Server`的路由列表。
- `Server`新增`Use`方法,该方法为`BindMiddlewareDefault`的别名,用以全局中间件的注册。
- `Server`新增`RouteOverWrite`配置项,用于控制是否在注册路由冲突时自动覆盖,默认关闭并提示。
- `Server`新增`Graceful`配置项,用于在单服务场景下控制平滑重启特性的开启/关闭,默认开启。
- 完善单元测试。
1. `gtcp`
- 改进简单协议下的数据包发送接收功能。
- 将连接池默认的缓存过期时间`30`秒修改为`10`秒。
- 完善单元测试。
### `database`
1. `gdb`
- 新增`As`数据表别名方法。
- 改进数据表、字段的安全字符自动识别添加功能。
- 新增`DB`数据库对象切换方法。
- 新增`TX`链式操作事务支持方法。
- 完善单元测试。
### `os`
1. `gcfg`
- 新增`GetMapStrStr`方法。
1. `gcmd`
- 增加参数解析的`strict`严格参数,默认严格解析,不存在指定参数/选项名称时则报错返回。
1. `genv`
- 改进`Remove`方法支持多个环境变量的删除。
1. `gfile`
- 改进`TempDir`临时目录获取方法,在`*nix`系统下默认为`/tmp`目录。
- 新增`ReadLines`, `ReadByteLines`方法,用以按行回调读取文件内容。
- 新增`Copy*`方法,用以文件/目录的拷贝,支持递归。
- 新增`Replace*`方法,用以目录下的文件内容替换,支持递归。
- 改进`Scan*`方法,用以检索并返回指定目录下的所有文件/目录,支持文件模式指定,支持递归。
- 完善单元测试。
1. `gproc`
- 改进命令行运行方法。
- 改进`Shell`命令文件检索逻辑。
- 改进实验性的进程间通信设计。
1. `gtime`
- 将包方法以及`Time`对象的时间戳方法`Second`, `Millisecond`, `Microsecond`, `Nanosecond`标记为废除,
并新增`Timestamp`, `TimestampMilli`, `TimestampMicro`, `TimestampNano`替换。
- 需要注意的是以上修改可能和老版本存在兼容性问题。
1. `gview`
- 解析功能、缓存设计改进。
- 新增`encode`, `decode`HTML编码/解码模板函数。
- 新增`concat`字符串拼接模板函数。
- 新增`dump`模板函数,功能类似于`g.Dump`方法。
- 新增`AutoEncode`配置项,用于自动转码输出的`HTML`内容,常用于防止`XSS`,默认关闭。需要注意的是该特性并不会影响`include`内置函数: https://goframe.org/os/gview/xss
- 单元测试完善。
### `crypto`
1. `gmd5`
- 增加`MustEncrypt`, `MustEncryptBytes`, `MustEncryptString`, `MustEncryptFile`方法。
1. `gsha1`
- 增加`MustEncryptFile`方法
### `encoding`
1. `gbase64`
- 新增`MustEncodeFile`, `MustEncodeFileToString`, `MustDecode`, `MustDecodeToString`方法。
1. `gjson`/`gparser`
- 新增`GetMapStrStr`方法。
- 新增`Must*`方法,用于指定数据格式的转换失败时产生`panic`错误,而不会返回`error`参数。
### `util`
1. `gconv`
- 改进`Convert`方法增加对`[]int32`, `[]int64`, `[]uint`, `[]uint32`, `[]uint64`, `[]float32`, `[]float64`数据类型的转换支持。
- 改进`String`字符串转换方法对指针参数的支持。
- 改进`Map*` Map转换方法的代码结构及性能。
- 新增`Floats`, `Float32s`, `Float64s`对`[]float32`, `[]float64`类型转换方法。
- 新增`Ints`, `Int32s`, `Int64s`对`[]int`, `[]int32`, `[]int64`类型转换方法。
- 新增`Uints`, `Uint32s`, `Uint64s`对`[]uint`, `[]uint32`, `[]uint64`类型转换方法。
- 完善单元测试。
### `frame`
1. `gins`
- 所有的单例对象在获取失败时产生`panic`错误。
## Bug Fix
1. 增加对常见错误路由格式例如`/user//index`的兼容支持。
1. 修复`gtcp`/`gudp`在数据接收时的间隔时间单位问题。
1. 修复`gfile`/`gspath`/`gfsnotify`包对文件的存在性判断不严谨问题。
1. 修复`gproc.Kill`方法在`windows`系统下的运行阻塞问题。
1. 修复`gstr.TrimLeftStr`/`gstr.TrimRightStr`在被替换字符串长度小于替换字符串长度时的数组溢出问题。
# `v1.10.0` (2019-12-05)
各位`gfer`久等了,较上一次发布时间过去已有两个多月了,这段时间`GF`也在不断地迭代改进,细节比较多,拟了个大概,以下是`release log`。

View File

@ -1,3 +1,5 @@
> This markdown is deprecated and will be removed in future. All TODO features are staged in the issue: https://github.com/gogf/gf/issues
# ON THE WAY
1. 增加图形验证码支持,至少支持数字和英文字母;
1. Cookie&Session数据池化处理
@ -10,7 +12,6 @@
1. gjson对大json数据的解析效率问题
1. ghttp增加route name特性并同时支持backend和template(提供内置函数)引用可以通过RedirectRoute方法给定route name和路由参数跳转到指定的路由地址上
1. gvalid校验支持当第一个规则失败后便不再校验后续的规则最好做成链式操作
1. gvalid增加支持对[]rune的长度校验(一个中文占3个字节)
1. ghttp.Request增加对输入参数的自动HtmlEncode机制
1. 常量命名风格根据golint进行修改
1. 开放rwmutex包并将gjson的互斥锁使用自定义的mutex替换
@ -21,8 +22,6 @@
- ghttp Server&Client basic auth、
- glog分类&日志等级&链式操作、gdb debug自动输出调试信息、gmlock内存锁、
1. 服务注册域名增加对泛域名的支持;
1. Cookie设置中文失效问题
1. 使用gconv将slice映射到struct属性上例如redis hscan的结果集
1. 项目参考:
- https://github.com/namreg/godown
- https://github.com/Masterminds/sprig
@ -31,32 +30,36 @@
1. 路由增加不区分大小写得匹配方式;
1. 改进WebServer获取POST参数处理逻辑当提交非form数据时例如json数据针对某些方法可以直接解析
1. WebServer增加可选择的路由覆盖配置默认情况下不覆盖
1. grpool性能压测结果变慢的问题
1. 增加jumplist的数据结构容器
1. DelayQueue/PriorityQueue
1. 权限管理模块;
1. 从ghttp中剥离SESSION功能构成单独的模块gsession
1. 改进gproc进程间通信处理逻辑提高稳定性以应对进程间大批量的数据发送/接收;
1. ghttp的热重启的本地进程端口监听在不使用该特性时默认关闭掉
1. gtcp增加对TLS加密通信的支持
1. 添加Save/Replace/BatchSave/BatchReplace方法对sqlite数据库的支持
1. 添加sqlite数据库的单元测试用例
1. gredis增加cluster支持
1. gset.Add/Remove/Contains方法增加批量操作支持
1. gmlock增加手动清理机制当内存锁不再使用时由调用端决定是否清理内存锁
1. gtimer增加DelayAdd*方法返回Entry对象以便DelayAdd*的定时任务也能进行状态控制gcron同理需要改进
1. 改进gdb对pgsql/mssql/oracle的支持使用方法覆盖的方式改进操作而不是完全依靠正则替换的方式
1. gdb的Cache缓存功能增加可自定义缓存接口以便支持外部缓存功能缓存接口可以通过io.ReadWriter接口实现
1. grpool增加支持阻塞添加任务接口
1. gdb.Model在链式安全的对象创建中增加sync.Pool的使用
1. 增加g.Table快捷方法以方便操作数据表但是得考虑后续模型操作设计特别是脚手架的模型管理
1. 改进ghttp分组路由中对hook的支持方式以便格式与BindHookHandler统一
# DONE
1. Cookie设置中文失效问题
1. gvalid增加支持对[]rune的长度校验(一个中文占3个字节)
1. grpool性能压测结果变慢的问题
1. ghttp的热重启的本地进程端口监听在不使用该特性时默认关闭掉
1. gtcp增加对TLS加密通信的支持
1. 改进gdb对pgsql/mssql/oracle的支持使用方法覆盖的方式改进操作而不是完全依靠正则替换的方式
1. gdb的Cache缓存功能增加可自定义缓存接口以便支持外部缓存功能缓存接口可以通过io.ReadWriter接口实现
1. 改进ghttp分组路由中对hook的支持方式以便格式与BindHookHandler统一
1. 使用gconv将slice映射到struct属性上例如redis hscan的结果集
1. gconv完善针对不同类型的判断例如尽量减少sprintf("%v", xxx)来执行string类型的转换
2. ghttp.Server请求执行中增加服务退出的方法不再执行后续操作
3. ghttp.Response对象完善并改进数据返回方法(Write/WriteString)

View File

@ -9,6 +9,7 @@ package garray
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/gogf/gf/internal/empty"
"github.com/gogf/gf/text/gstr"
@ -20,6 +21,7 @@ import (
"github.com/gogf/gf/util/grand"
)
// Array is a golang array with rich features.
type Array struct {
mu *rwmutex.RWMutex
array []interface{}
@ -94,21 +96,26 @@ func NewArrayFromCopy(array []interface{}, safe ...bool) *Array {
}
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *Array) Get(index int) interface{} {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *Array) Get(index int) (value interface{}, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return nil, false
}
return a.array[index], true
}
// Set sets value to specified index.
func (a *Array) Set(index int, value interface{}) *Array {
func (a *Array) Set(index int, value interface{}) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
a.array[index] = value
return a
return nil
}
// SetArray sets the underlying slice array with the given <array>.
@ -154,48 +161,60 @@ func (a *Array) SortFunc(less func(v1, v2 interface{}) bool) *Array {
}
// InsertBefore inserts the <value> to the front of <index>.
func (a *Array) InsertBefore(index int, value interface{}) *Array {
a.mu.Lock()
defer a.mu.Unlock()
rear := append([]interface{}{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return a
}
// InsertAfter inserts the <value> to the back of <index>.
func (a *Array) InsertAfter(index int, value interface{}) *Array {
a.mu.Lock()
defer a.mu.Unlock()
rear := append([]interface{}{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return a
}
// Remove removes an item by index.
func (a *Array) Remove(index int) interface{} {
func (a *Array) InsertBefore(index int, value interface{}) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return nil
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
// Determine array boundaries when deleting to improve deletion efficiency。
rear := append([]interface{}{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return nil
}
// InsertAfter inserts the <value> to the back of <index>.
func (a *Array) InsertAfter(index int, value interface{}) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
rear := append([]interface{}{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return nil
}
// Remove removes an item by index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *Array) Remove(index int) (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *Array) doRemoveWithoutLock(index int) (value interface{}, found bool) {
if index < 0 || index >= len(a.array) {
return nil, false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// If it is a non-boundary delete,
// it will involve the creation of an array,
// then the deletion is less efficient.
value := a.array[index]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
@ -226,52 +245,68 @@ func (a *Array) PushRight(value ...interface{}) *Array {
}
// PopRand randomly pops and return an item out of array.
func (a *Array) PopRand() interface{} {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *Array) PopRand() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
func (a *Array) PopRands(size int) []interface{} {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]interface{}, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
// PopLeft pops and returns an item from the beginning of array.
func (a *Array) PopLeft() interface{} {
// Note that if the array is empty, the <found> is false.
func (a *Array) PopLeft() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
value := a.array[0]
if len(a.array) == 0 {
return nil, false
}
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
func (a *Array) PopRight() interface{} {
// Note that if the array is empty, the <found> is false.
func (a *Array) PopRight() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
value := a.array[index]
if index <= 0 {
return nil, false
}
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// PopLefts pops and returns <size> items from the beginning of array.
func (a *Array) PopLefts(size int) []interface{} {
a.mu.Lock()
defer a.mu.Unlock()
length := len(a.array)
if size > length {
size = length
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
@ -282,9 +317,14 @@ func (a *Array) PopLefts(size int) []interface{} {
func (a *Array) PopRights(size int) []interface{} {
a.mu.Lock()
defer a.mu.Unlock()
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -514,11 +554,11 @@ func (a *Array) Merge(array interface{}) *Array {
// Fill fills an array with num entries of the value <value>,
// keys starting at the <startIndex> parameter.
func (a *Array) Fill(startIndex int, num int, value interface{}) *Array {
func (a *Array) Fill(startIndex int, num int, value interface{}) error {
a.mu.Lock()
defer a.mu.Unlock()
if startIndex < 0 {
startIndex = 0
if startIndex < 0 || startIndex > len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", startIndex, len(a.array)))
}
for i := startIndex; i < startIndex+num; i++ {
if i > len(a.array)-1 {
@ -527,7 +567,7 @@ func (a *Array) Fill(startIndex int, num int, value interface{}) *Array {
a.array[i] = value
}
}
return a
return nil
}
// Chunk splits an array into multiple arrays,
@ -581,27 +621,27 @@ func (a *Array) Pad(size int, val interface{}) *Array {
}
// Rand randomly returns one item from array(no deleting).
func (a *Array) Rand() interface{} {
func (a *Array) Rand() (value interface{}, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return nil, false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *Array) Rands(size int) []interface{} {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]interface{}, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]interface{}, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Shuffle randomly shuffles the array.
@ -765,3 +805,8 @@ func (a *Array) FilterEmpty() *Array {
}
return a
}
// IsEmpty checks whether the array is empty.
func (a *Array) IsEmpty() bool {
return a.Len() == 0
}

View File

@ -9,6 +9,7 @@ package garray
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"math"
"sort"
@ -18,6 +19,7 @@ import (
"github.com/gogf/gf/util/grand"
)
// IntArray is a golang int array with rich features.
type IntArray struct {
mu *rwmutex.RWMutex
array []int
@ -77,21 +79,26 @@ func NewIntArrayFromCopy(array []int, safe ...bool) *IntArray {
}
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *IntArray) Get(index int) int {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *IntArray) Get(index int) (value int, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return 0, false
}
return a.array[index], true
}
// Set sets value to specified index.
func (a *IntArray) Set(index int, value int) *IntArray {
func (a *IntArray) Set(index int, value int) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
a.array[index] = value
return a
return nil
}
// SetArray sets the underlying slice array with the given <array>.
@ -127,8 +134,7 @@ func (a *IntArray) Sum() (sum int) {
}
// Sort sorts the array in increasing order.
// The parameter <reverse> controls whether sort
// in increasing order(default) or decreasing order
// The parameter <reverse> controls whether sort in increasing order(default) or decreasing order.
func (a *IntArray) Sort(reverse ...bool) *IntArray {
a.mu.Lock()
defer a.mu.Unlock()
@ -156,56 +162,68 @@ func (a *IntArray) SortFunc(less func(v1, v2 int) bool) *IntArray {
}
// InsertBefore inserts the <value> to the front of <index>.
func (a *IntArray) InsertBefore(index int, value int) *IntArray {
a.mu.Lock()
defer a.mu.Unlock()
rear := append([]int{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return a
}
// InsertAfter inserts the <value> to the back of <index>.
func (a *IntArray) InsertAfter(index int, value int) *IntArray {
a.mu.Lock()
defer a.mu.Unlock()
rear := append([]int{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return a
}
// Remove removes an item by index.
func (a *IntArray) Remove(index int) int {
func (a *IntArray) InsertBefore(index int, value int) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return 0
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
rear := append([]int{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return nil
}
// InsertAfter inserts the <value> to the back of <index>.
func (a *IntArray) InsertAfter(index int, value int) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
rear := append([]int{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return nil
}
// Remove removes an item by index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *IntArray) Remove(index int) (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *IntArray) doRemoveWithoutLock(index int) (value int, found bool) {
if index < 0 || index >= len(a.array) {
return 0, false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// If it is a non-boundary delete,
// it will involve the creation of an array,
// then the deletion is less efficient.
value := a.array[index]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
// It returns true if value is found in the array, or else false if not found.
func (a *IntArray) RemoveValue(value int) bool {
if i := a.Search(value); i != -1 {
a.Remove(i)
return true
_, found := a.Remove(i)
return found
}
return false
}
@ -228,52 +246,72 @@ func (a *IntArray) PushRight(value ...int) *IntArray {
}
// PopLeft pops and returns an item from the beginning of array.
func (a *IntArray) PopLeft() int {
// Note that if the array is empty, the <found> is false.
func (a *IntArray) PopLeft() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
value := a.array[0]
if len(a.array) == 0 {
return 0, false
}
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
func (a *IntArray) PopRight() int {
// Note that if the array is empty, the <found> is false.
func (a *IntArray) PopRight() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
value := a.array[index]
if index <= 0 {
return 0, false
}
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// PopRand randomly pops and return an item out of array.
func (a *IntArray) PopRand() int {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *IntArray) PopRand() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *IntArray) PopRands(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]int, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
// PopLefts pops and returns <size> items from the beginning of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *IntArray) PopLefts(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
length := len(a.array)
if size > length {
size = length
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
@ -281,12 +319,19 @@ func (a *IntArray) PopLefts(size int) []int {
}
// PopRights pops and returns <size> items from the end of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *IntArray) PopRights(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -511,11 +556,11 @@ func (a *IntArray) Merge(array interface{}) *IntArray {
// Fill fills an array with num entries of the value <value>,
// keys starting at the <startIndex> parameter.
func (a *IntArray) Fill(startIndex int, num int, value int) *IntArray {
func (a *IntArray) Fill(startIndex int, num int, value int) error {
a.mu.Lock()
defer a.mu.Unlock()
if startIndex < 0 {
startIndex = 0
if startIndex < 0 || startIndex > len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", startIndex, len(a.array)))
}
for i := startIndex; i < startIndex+num; i++ {
if i > len(a.array)-1 {
@ -524,7 +569,7 @@ func (a *IntArray) Fill(startIndex int, num int, value int) *IntArray {
a.array[i] = value
}
}
return a
return nil
}
// Chunk splits an array into multiple arrays,
@ -578,27 +623,27 @@ func (a *IntArray) Pad(size int, value int) *IntArray {
}
// Rand randomly returns one item from array(no deleting).
func (a *IntArray) Rand() int {
func (a *IntArray) Rand() (value int, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return 0, false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *IntArray) Rands(size int) []int {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]int, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]int, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Shuffle randomly shuffles the array.
@ -730,3 +775,8 @@ func (a *IntArray) FilterEmpty() *IntArray {
}
return a
}
// IsEmpty checks whether the array is empty.
func (a *IntArray) IsEmpty() bool {
return a.Len() == 0
}

View File

@ -9,6 +9,8 @@ package garray
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/gogf/gf/text/gstr"
"math"
"sort"
@ -19,6 +21,7 @@ import (
"github.com/gogf/gf/util/grand"
)
// StrArray is a golang string array with rich features.
type StrArray struct {
mu *rwmutex.RWMutex
array []string
@ -63,21 +66,26 @@ func NewStrArrayFromCopy(array []string, safe ...bool) *StrArray {
}
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *StrArray) Get(index int) string {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *StrArray) Get(index int) (value string, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return "", false
}
return a.array[index], true
}
// Set sets value to specified index.
func (a *StrArray) Set(index int, value string) *StrArray {
func (a *StrArray) Set(index int, value string) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
a.array[index] = value
return a
return nil
}
// SetArray sets the underlying slice array with the given <array>.
@ -142,56 +150,68 @@ func (a *StrArray) SortFunc(less func(v1, v2 string) bool) *StrArray {
}
// InsertBefore inserts the <value> to the front of <index>.
func (a *StrArray) InsertBefore(index int, value string) *StrArray {
a.mu.Lock()
defer a.mu.Unlock()
rear := append([]string{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return a
}
// InsertAfter inserts the <value> to the back of <index>.
func (a *StrArray) InsertAfter(index int, value string) *StrArray {
a.mu.Lock()
defer a.mu.Unlock()
rear := append([]string{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return a
}
// Remove removes an item by index.
func (a *StrArray) Remove(index int) string {
func (a *StrArray) InsertBefore(index int, value string) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return ""
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
// Determine array boundaries when deleting to improve deletion efficiency。
rear := append([]string{}, a.array[index:]...)
a.array = append(a.array[0:index], value)
a.array = append(a.array, rear...)
return nil
}
// InsertAfter inserts the <value> to the back of <index>.
func (a *StrArray) InsertAfter(index int, value string) error {
a.mu.Lock()
defer a.mu.Unlock()
if index < 0 || index >= len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", index, len(a.array)))
}
rear := append([]string{}, a.array[index+1:]...)
a.array = append(a.array[0:index+1], value)
a.array = append(a.array, rear...)
return nil
}
// Remove removes an item by index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *StrArray) Remove(index int) (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *StrArray) doRemoveWithoutLock(index int) (value string, found bool) {
if index < 0 || index >= len(a.array) {
return "", false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// If it is a non-boundary delete,
// it will involve the creation of an array,
// then the deletion is less efficient.
value := a.array[index]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
// It returns true if value is found in the array, or else false if not found.
func (a *StrArray) RemoveValue(value string) bool {
if i := a.Search(value); i != -1 {
a.Remove(i)
return true
_, found := a.Remove(i)
return found
}
return false
}
@ -214,52 +234,72 @@ func (a *StrArray) PushRight(value ...string) *StrArray {
}
// PopLeft pops and returns an item from the beginning of array.
func (a *StrArray) PopLeft() string {
// Note that if the array is empty, the <found> is false.
func (a *StrArray) PopLeft() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
value := a.array[0]
if len(a.array) == 0 {
return "", false
}
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
func (a *StrArray) PopRight() string {
// Note that if the array is empty, the <found> is false.
func (a *StrArray) PopRight() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
value := a.array[index]
if index <= 0 {
return "", false
}
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// PopRand randomly pops and return an item out of array.
func (a *StrArray) PopRand() string {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *StrArray) PopRand() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *StrArray) PopRands(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]string, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
// PopLefts pops and returns <size> items from the beginning of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *StrArray) PopLefts(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
length := len(a.array)
if size > length {
size = length
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
@ -267,12 +307,19 @@ func (a *StrArray) PopLefts(size int) []string {
}
// PopRights pops and returns <size> items from the end of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *StrArray) PopRights(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -500,11 +547,11 @@ func (a *StrArray) Merge(array interface{}) *StrArray {
// Fill fills an array with num entries of the value <value>,
// keys starting at the <startIndex> parameter.
func (a *StrArray) Fill(startIndex int, num int, value string) *StrArray {
func (a *StrArray) Fill(startIndex int, num int, value string) error {
a.mu.Lock()
defer a.mu.Unlock()
if startIndex < 0 {
startIndex = 0
if startIndex < 0 || startIndex > len(a.array) {
return errors.New(fmt.Sprintf("index %d out of array range %d", startIndex, len(a.array)))
}
for i := startIndex; i < startIndex+num; i++ {
if i > len(a.array)-1 {
@ -513,7 +560,7 @@ func (a *StrArray) Fill(startIndex int, num int, value string) *StrArray {
a.array[i] = value
}
}
return a
return nil
}
// Chunk splits an array into multiple arrays,
@ -567,27 +614,27 @@ func (a *StrArray) Pad(size int, value string) *StrArray {
}
// Rand randomly returns one item from array(no deleting).
func (a *StrArray) Rand() string {
func (a *StrArray) Rand() (value string, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return "", false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *StrArray) Rands(size int) []string {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]string, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]string, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Shuffle randomly shuffles the array.
@ -730,3 +777,8 @@ func (a *StrArray) FilterEmpty() *StrArray {
}
return a
}
// IsEmpty checks whether the array is empty.
func (a *StrArray) IsEmpty() bool {
return a.Len() == 0
}

View File

@ -22,6 +22,7 @@ import (
"github.com/gogf/gf/util/grand"
)
// SortedArray is a golang sorted array with rich features.
// It's using increasing order in default.
type SortedArray struct {
mu *rwmutex.RWMutex
@ -148,38 +149,46 @@ func (a *SortedArray) Add(values ...interface{}) *SortedArray {
return a
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *SortedArray) Get(index int) interface{} {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedArray) Get(index int) (value interface{}, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return nil, false
}
return a.array[index], true
}
// Remove removes an item by index.
func (a *SortedArray) Remove(index int) interface{} {
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedArray) Remove(index int) (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *SortedArray) doRemoveWithoutLock(index int) (value interface{}, found bool) {
if index < 0 || index >= len(a.array) {
return nil
return nil, false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// If it is a non-boundary delete,
// it will involve the creation of an array,
// then the deletion is less efficient.
value := a.array[index]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
@ -193,41 +202,53 @@ func (a *SortedArray) RemoveValue(value interface{}) bool {
}
// PopLeft pops and returns an item from the beginning of array.
func (a *SortedArray) PopLeft() interface{} {
// Note that if the array is empty, the <found> is false.
func (a *SortedArray) PopLeft() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
value := a.array[0]
if len(a.array) == 0 {
return nil, false
}
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
func (a *SortedArray) PopRight() interface{} {
// Note that if the array is empty, the <found> is false.
func (a *SortedArray) PopRight() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
value := a.array[index]
if index <= 0 {
return nil, false
}
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// PopRand randomly pops and return an item out of array.
func (a *SortedArray) PopRand() interface{} {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *SortedArray) PopRand() (value interface{}, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
func (a *SortedArray) PopRands(size int) []interface{} {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]interface{}, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
@ -236,9 +257,13 @@ func (a *SortedArray) PopRands(size int) []interface{} {
func (a *SortedArray) PopLefts(size int) []interface{} {
a.mu.Lock()
defer a.mu.Unlock()
length := len(a.array)
if size > length {
size = length
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
@ -249,9 +274,14 @@ func (a *SortedArray) PopLefts(size int) []interface{} {
func (a *SortedArray) PopRights(size int) []interface{} {
a.mu.Lock()
defer a.mu.Unlock()
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -539,27 +569,27 @@ func (a *SortedArray) Chunk(size int) [][]interface{} {
}
// Rand randomly returns one item from array(no deleting).
func (a *SortedArray) Rand() interface{} {
func (a *SortedArray) Rand() (value interface{}, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return nil, false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *SortedArray) Rands(size int) []interface{} {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]interface{}, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]interface{}, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Join joins array elements with a string <glue>.
@ -733,3 +763,8 @@ func (a *SortedArray) FilterEmpty() *SortedArray {
}
return a
}
// IsEmpty checks whether the array is empty.
func (a *SortedArray) IsEmpty() bool {
return a.Len() == 0
}

View File

@ -19,6 +19,7 @@ import (
"github.com/gogf/gf/util/grand"
)
// SortedIntArray is a golang sorted int array with rich features.
// It's using increasing order in default.
type SortedIntArray struct {
mu *rwmutex.RWMutex
@ -133,97 +134,125 @@ func (a *SortedIntArray) Add(values ...int) *SortedIntArray {
return a
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *SortedIntArray) Get(index int) int {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedIntArray) Get(index int) (value int, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return 0, false
}
return a.array[index], true
}
// Remove removes an item by index.
func (a *SortedIntArray) Remove(index int) int {
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedIntArray) Remove(index int) (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *SortedIntArray) doRemoveWithoutLock(index int) (value int, found bool) {
if index < 0 || index >= len(a.array) {
return 0
return 0, false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// If it is a non-boundary delete,
// it will involve the creation of an array,
// then the deletion is less efficient.
value := a.array[index]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
// It returns true if value is found in the array, or else false if not found.
func (a *SortedIntArray) RemoveValue(value int) bool {
if i := a.Search(value); i != -1 {
a.Remove(i)
return true
_, found := a.Remove(i)
return found
}
return false
}
// PopLeft pops and returns an item from the beginning of array.
func (a *SortedIntArray) PopLeft() int {
// Note that if the array is empty, the <found> is false.
func (a *SortedIntArray) PopLeft() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
value := a.array[0]
if len(a.array) == 0 {
return 0, false
}
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
func (a *SortedIntArray) PopRight() int {
// Note that if the array is empty, the <found> is false.
func (a *SortedIntArray) PopRight() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
value := a.array[index]
if index <= 0 {
return 0, false
}
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// PopRand randomly pops and return an item out of array.
func (a *SortedIntArray) PopRand() int {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *SortedIntArray) PopRand() (value int, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedIntArray) PopRands(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]int, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
// PopLefts pops and returns <size> items from the beginning of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedIntArray) PopLefts(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
length := len(a.array)
if size > length {
size = length
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
@ -231,12 +260,19 @@ func (a *SortedIntArray) PopLefts(size int) []int {
}
// PopRights pops and returns <size> items from the end of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedIntArray) PopRights(size int) []int {
a.mu.Lock()
defer a.mu.Unlock()
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -530,27 +566,27 @@ func (a *SortedIntArray) Chunk(size int) [][]int {
}
// Rand randomly returns one item from array(no deleting).
func (a *SortedIntArray) Rand() int {
func (a *SortedIntArray) Rand() (value int, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return 0, false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *SortedIntArray) Rands(size int) []int {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]int, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]int, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Join joins array elements with a string <glue>.
@ -680,3 +716,8 @@ func (a *SortedIntArray) FilterEmpty() *SortedIntArray {
}
return a
}
// IsEmpty checks whether the array is empty.
func (a *SortedIntArray) IsEmpty() bool {
return a.Len() == 0
}

View File

@ -19,6 +19,7 @@ import (
"github.com/gogf/gf/util/grand"
)
// SortedStrArray is a golang sorted string array with rich features.
// It's using increasing order in default.
type SortedStrArray struct {
mu *rwmutex.RWMutex
@ -118,38 +119,46 @@ func (a *SortedStrArray) Add(values ...string) *SortedStrArray {
return a
}
// Get returns the value of the specified index,
// the caller should notice the boundary of the array.
func (a *SortedStrArray) Get(index int) string {
// Get returns the value by the specified index.
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedStrArray) Get(index int) (value string, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
value := a.array[index]
return value
if index < 0 || index >= len(a.array) {
return "", false
}
return a.array[index], true
}
// Remove removes an item by index.
func (a *SortedStrArray) Remove(index int) string {
// If the given <index> is out of range of the array, the <found> is false.
func (a *SortedStrArray) Remove(index int) (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(index)
}
// doRemoveWithoutLock removes an item by index without lock.
func (a *SortedStrArray) doRemoveWithoutLock(index int) (value string, found bool) {
if index < 0 || index >= len(a.array) {
return ""
return "", false
}
// Determine array boundaries when deleting to improve deletion efficiency.
if index == 0 {
value := a.array[0]
a.array = a.array[1:]
return value
return value, true
} else if index == len(a.array)-1 {
value := a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// If it is a non-boundary delete,
// it will involve the creation of an array,
// then the deletion is less efficient.
value := a.array[index]
value = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
return value
return value, true
}
// RemoveValue removes an item by value.
@ -163,52 +172,72 @@ func (a *SortedStrArray) RemoveValue(value string) bool {
}
// PopLeft pops and returns an item from the beginning of array.
func (a *SortedStrArray) PopLeft() string {
// Note that if the array is empty, the <found> is false.
func (a *SortedStrArray) PopLeft() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
value := a.array[0]
if len(a.array) == 0 {
return "", false
}
value = a.array[0]
a.array = a.array[1:]
return value
return value, true
}
// PopRight pops and returns an item from the end of array.
func (a *SortedStrArray) PopRight() string {
// Note that if the array is empty, the <found> is false.
func (a *SortedStrArray) PopRight() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
index := len(a.array) - 1
value := a.array[index]
if index <= 0 {
return "", false
}
value = a.array[index]
a.array = a.array[:index]
return value
return value, true
}
// PopRand randomly pops and return an item out of array.
func (a *SortedStrArray) PopRand() string {
return a.Remove(grand.Intn(len(a.array)))
// Note that if the array is empty, the <found> is false.
func (a *SortedStrArray) PopRand() (value string, found bool) {
a.mu.Lock()
defer a.mu.Unlock()
return a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
// PopRands randomly pops and returns <size> items out of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedStrArray) PopRands(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
if size > len(a.array) {
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
size = len(a.array)
}
array := make([]string, size)
for i := 0; i < size; i++ {
index := grand.Intn(len(a.array))
array[i] = a.array[index]
a.array = append(a.array[:index], a.array[index+1:]...)
array[i], _ = a.doRemoveWithoutLock(grand.Intn(len(a.array)))
}
return array
}
// PopLefts pops and returns <size> items from the beginning of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedStrArray) PopLefts(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
length := len(a.array)
if size > length {
size = length
if size <= 0 || len(a.array) == 0 {
return nil
}
if size >= len(a.array) {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[0:size]
a.array = a.array[size:]
@ -216,12 +245,19 @@ func (a *SortedStrArray) PopLefts(size int) []string {
}
// PopRights pops and returns <size> items from the end of array.
// If the given <size> is greater than size of the array, it returns all elements of the array.
// Note that if given <size> <= 0 or the array is empty, it returns nil.
func (a *SortedStrArray) PopRights(size int) []string {
a.mu.Lock()
defer a.mu.Unlock()
if size <= 0 || len(a.array) == 0 {
return nil
}
index := len(a.array) - size
if index < 0 {
index = 0
if index <= 0 {
array := a.array
a.array = a.array[:0]
return array
}
value := a.array[index:]
a.array = a.array[:index]
@ -515,27 +551,27 @@ func (a *SortedStrArray) Chunk(size int) [][]string {
}
// Rand randomly returns one item from array(no deleting).
func (a *SortedStrArray) Rand() string {
func (a *SortedStrArray) Rand() (value string, found bool) {
a.mu.RLock()
defer a.mu.RUnlock()
return a.array[grand.Intn(len(a.array))]
if len(a.array) == 0 {
return "", false
}
return a.array[grand.Intn(len(a.array))], true
}
// Rands randomly returns <size> items from array(no deleting).
func (a *SortedStrArray) Rands(size int) []string {
a.mu.RLock()
defer a.mu.RUnlock()
if size > len(a.array) {
size = len(a.array)
if size <= 0 || len(a.array) == 0 {
return nil
}
n := make([]string, size)
for i, v := range grand.Perm(len(a.array)) {
n[i] = a.array[v]
if i == size-1 {
break
}
array := make([]string, size)
for i := 0; i < size; i++ {
array[i] = a.array[grand.Intn(len(a.array))]
}
return n
return array
}
// Join joins array elements with a string <glue>.
@ -676,3 +712,8 @@ func (a *SortedStrArray) FilterEmpty() *SortedStrArray {
}
return a
}
// IsEmpty checks whether the array is empty.
func (a *SortedStrArray) IsEmpty() bool {
return a.Len() == 0
}

View File

@ -8,51 +8,52 @@ package garray_test
import (
"fmt"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/container/garray"
)
func Example_basic() {
// 创建普通的数组
// A normal array.
a := garray.New()
// 添加数据项
// Adding items.
for i := 0; i < 10; i++ {
a.Append(i)
}
// 获取当前数组长度
// Print the array length.
fmt.Println(a.Len())
// 获取当前数据项列表
// Print the array items.
fmt.Println(a.Slice())
// 获取指定索引项
// Retrieve item by index.
fmt.Println(a.Get(6))
// 查找指定数据项是否存在
// Check item existence.
fmt.Println(a.Contains(6))
fmt.Println(a.Contains(100))
// 在指定索引前插入数据项
// Insert item before specified index.
a.InsertAfter(9, 11)
// 在指定索引后插入数据项
// Insert item after specified index.
a.InsertBefore(10, 10)
fmt.Println(a.Slice())
// 修改指定索引的数据项
// Modify item by index.
a.Set(0, 100)
fmt.Println(a.Slice())
// 搜索数据项,返回搜索到的索引位置
// Search item and return its index.
fmt.Println(a.Search(5))
// 删除指定索引的数据项
// Remove item by index.
a.Remove(0)
fmt.Println(a.Slice())
// 清空数组
// Empty the array, removes all items of it.
fmt.Println(a.Slice())
a.Clear()
fmt.Println(a.Slice())
@ -60,7 +61,7 @@ func Example_basic() {
// Output:
// 10
// [0 1 2 3 4 5 6 7 8 9]
// 6
// 6 true
// true
// false
// [0 1 2 3 4 5 6 7 8 9 10 11]
@ -73,26 +74,34 @@ func Example_basic() {
func Example_rand() {
array := garray.NewFrom([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9})
// 随机返回两个数据项(不删除)
// Randomly retrieve and return 2 items from the array.
// It does not delete the items from array.
fmt.Println(array.Rands(2))
// Randomly pick and return one item from the array.
// It deletes the picked up item from array.
fmt.Println(array.PopRand())
}
func Example_pop() {
func Example_popItem() {
array := garray.NewFrom([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9})
// Any Pop* functions pick, delete and return the item from array.
fmt.Println(array.PopLeft())
fmt.Println(array.PopLefts(2))
fmt.Println(array.PopRight())
fmt.Println(array.PopRights(2))
// Output:
// 1
// 1 true
// [2 3]
// 9
// 9 true
// [7 8]
}
func Example_merge() {
func Example_mergeArray() {
array1 := garray.NewFrom([]interface{}{1, 2})
array2 := garray.NewFrom([]interface{}{3, 4})
slice1 := []interface{}{5, 6}
@ -110,3 +119,14 @@ func Example_merge() {
// [1 2]
// [1 2 1 2 3 4 5 6 7 8 9 0]
}
func Example_filter() {
array1 := garray.NewFrom(g.Slice{0, 1, 2, nil, "", g.Slice{}, "john"})
array2 := garray.NewFrom(g.Slice{0, 1, 2, nil, "", g.Slice{}, "john"})
fmt.Printf("%#v\n", array1.FilterNil().Slice())
fmt.Printf("%#v\n", array2.FilterEmpty().Slice())
// Output:
// []interface {}{0, 1, 2, "", []interface {}{}, "john"}
// []interface {}{1, 2, "john"}
}

View File

@ -18,89 +18,103 @@ 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.C(t, func(t *gtest.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()
t.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.Assert(array.Add().Slice(), expect)
gtest.C(t, func(t *gtest.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)
}
t.Assert(array.Slice(), expect)
t.Assert(array.Add().Slice(), expect)
})
}
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.C(t, func(t *gtest.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)
}
t.Assert(array.Slice(), expect)
})
}
func Test_SortedStrArray1(t *testing.T) {
expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"}
array1 := garray.NewSortedStrArray()
array2 := garray.NewSortedStrArray(true)
for i := 10; i > -1; i-- {
array1.Add(gconv.String(i))
array2.Add(gconv.String(i))
}
gtest.Assert(array1.Slice(), expect)
gtest.Assert(array2.Slice(), expect)
gtest.C(t, func(t *gtest.T) {
expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"}
array1 := garray.NewSortedStrArray()
array2 := garray.NewSortedStrArray(true)
for i := 10; i > -1; i-- {
array1.Add(gconv.String(i))
array2.Add(gconv.String(i))
}
t.Assert(array1.Slice(), expect)
t.Assert(array2.Slice(), expect)
})
}
func Test_SortedStrArray2(t *testing.T) {
expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"}
array := garray.NewSortedStrArray()
for i := 0; i <= 10; i++ {
array.Add(gconv.String(i))
}
gtest.Assert(array.Slice(), expect)
array.Add()
gtest.Assert(array.Slice(), expect)
gtest.C(t, func(t *gtest.T) {
expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"}
array := garray.NewSortedStrArray()
for i := 0; i <= 10; i++ {
array.Add(gconv.String(i))
}
t.Assert(array.Slice(), expect)
array.Add()
t.Assert(array.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.C(t, func(t *gtest.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))
})
for i := 10; i > -1; i-- {
array.Add(gconv.String(i))
}
t.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"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array := garray.NewSortedArray(func1)
array2 := garray.NewSortedArray(func1, true)
for i := 0; i <= 10; i++ {
array.Add(gconv.String(i))
array2.Add(gconv.String(i))
}
gtest.Assert(array.Slice(), expect)
gtest.Assert(array.Add().Slice(), expect)
gtest.Assert(array2.Slice(), expect)
gtest.C(t, func(t *gtest.T) {
expect := []string{"0", "1", "10", "2", "3", "4", "5", "6", "7", "8", "9"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array := garray.NewSortedArray(func1)
array2 := garray.NewSortedArray(func1, true)
for i := 0; i <= 10; i++ {
array.Add(gconv.String(i))
array2.Add(gconv.String(i))
}
t.Assert(array.Slice(), expect)
t.Assert(array.Add().Slice(), expect)
t.Assert(array2.Slice(), expect)
})
}
func TestNewFromCopy(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"100", "200", "300", "400", "500", "600"}
array1 := garray.NewFromCopy(a1)
gtest.AssertIN(array1.PopRands(2), a1)
gtest.Assert(len(array1.PopRands(1)), 1)
gtest.Assert(len(array1.PopRands(9)), 3)
t.AssertIN(array1.PopRands(2), a1)
t.Assert(len(array1.PopRands(1)), 1)
t.Assert(len(array1.PopRands(9)), 3)
})
}

View File

@ -20,41 +20,62 @@ import (
)
func Test_Array_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
expect := []interface{}{0, 1, 2, 3}
array := garray.NewArrayFrom(expect)
array2 := garray.NewArrayFrom(expect)
array3 := garray.NewArrayFrom([]interface{}{})
gtest.Assert(array.Slice(), expect)
gtest.Assert(array.Interfaces(), expect)
t.Assert(array.Slice(), expect)
t.Assert(array.Interfaces(), 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(array3.Search(100), -1)
gtest.Assert(array.Contains(100), true)
gtest.Assert(array.Remove(0), 100)
gtest.Assert(array.Remove(-1), nil)
gtest.Assert(array.Remove(100000), nil)
gtest.Assert(array2.Remove(3), 3)
gtest.Assert(array2.Remove(1), 1)
v, ok := array.Get(0)
t.Assert(v, 100)
t.Assert(ok, true)
gtest.Assert(array.Contains(100), false)
v, ok = array.Get(1)
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array.Search(100), 0)
t.Assert(array3.Search(100), -1)
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, nil)
t.Assert(ok, false)
v, ok = array.Remove(100000)
t.Assert(v, nil)
t.Assert(ok, false)
v, ok = array2.Remove(3)
t.Assert(v, 3)
t.Assert(ok, true)
v, ok = array2.Remove(1)
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array.Contains(100), false)
array.Append(4)
gtest.Assert(array.Len(), 4)
t.Assert(array.Len(), 4)
array.InsertBefore(0, 100)
array.InsertAfter(0, 200)
gtest.Assert(array.Slice(), []interface{}{100, 200, 2, 2, 3, 4})
t.Assert(array.Slice(), []interface{}{100, 200, 2, 2, 3, 4})
array.InsertBefore(5, 300)
array.InsertAfter(6, 400)
gtest.Assert(array.Slice(), []interface{}{100, 200, 2, 2, 3, 300, 4, 400})
gtest.Assert(array.Clear().Len(), 0)
t.Assert(array.Slice(), []interface{}{100, 200, 2, 2, 3, 300, 4, 400})
t.Assert(array.Clear().Len(), 0)
})
}
func TestArray_Sort(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
expect1 := []interface{}{0, 1, 2, 3}
expect2 := []interface{}{3, 2, 1, 0}
array := garray.NewArray()
@ -64,78 +85,109 @@ func TestArray_Sort(t *testing.T) {
array.SortFunc(func(v1, v2 interface{}) bool {
return v1.(int) < v2.(int)
})
gtest.Assert(array.Slice(), expect1)
t.Assert(array.Slice(), expect1)
array.SortFunc(func(v1, v2 interface{}) bool {
return v1.(int) > v2.(int)
})
gtest.Assert(array.Slice(), expect2)
t.Assert(array.Slice(), expect2)
})
}
func TestArray_Unique(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
expect := []interface{}{1, 1, 2, 3}
array := garray.NewArrayFrom(expect)
gtest.Assert(array.Unique().Slice(), []interface{}{1, 2, 3})
t.Assert(array.Unique().Slice(), []interface{}{1, 2, 3})
})
}
func TestArray_PushAndPop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
expect := []interface{}{0, 1, 2, 3}
array := garray.NewArrayFrom(expect)
gtest.Assert(array.Slice(), expect)
gtest.Assert(array.PopLeft(), 0)
gtest.Assert(array.PopRight(), 3)
gtest.AssertIN(array.PopRand(), []interface{}{1, 2})
gtest.AssertIN(array.PopRand(), []interface{}{1, 2})
gtest.Assert(array.Len(), 0)
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, []interface{}{1, 2})
t.Assert(ok, true)
v, ok = array.PopRand()
t.AssertIN(v, []interface{}{1, 2})
t.Assert(ok, true)
t.Assert(array.Len(), 0)
array.PushLeft(1).PushRight(2)
gtest.Assert(array.Slice(), []interface{}{1, 2})
t.Assert(array.Slice(), []interface{}{1, 2})
})
}
func TestArray_PopRands(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{100, 200, 300, 400, 500, 600}
array := garray.NewFromCopy(a1)
gtest.AssertIN(array.PopRands(2), []interface{}{100, 200, 300, 400, 500, 600})
t.AssertIN(array.PopRands(2), []interface{}{100, 200, 300, 400, 500, 600})
})
}
func TestArray_PopLeftsAndPopRights(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.New()
v, ok := array.PopLeft()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopLefts(10), nil)
v, ok = array.PopRight()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopRights(10), nil)
v, ok = array.PopRand()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopRands(10), nil)
})
gtest.C(t, func(t *gtest.T) {
value1 := []interface{}{0, 1, 2, 3, 4, 5, 6}
value2 := []interface{}{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewArrayFrom(value1)
array2 := garray.NewArrayFrom(value2)
gtest.Assert(array1.PopLefts(2), []interface{}{0, 1})
gtest.Assert(array1.Slice(), []interface{}{2, 3, 4, 5, 6})
gtest.Assert(array1.PopRights(2), []interface{}{5, 6})
gtest.Assert(array1.Slice(), []interface{}{2, 3, 4})
gtest.Assert(array1.PopRights(20), []interface{}{2, 3, 4})
gtest.Assert(array1.Slice(), []interface{}{})
gtest.Assert(array2.PopLefts(20), []interface{}{0, 1, 2, 3, 4, 5, 6})
gtest.Assert(array2.Slice(), []interface{}{})
t.Assert(array1.PopLefts(2), []interface{}{0, 1})
t.Assert(array1.Slice(), []interface{}{2, 3, 4, 5, 6})
t.Assert(array1.PopRights(2), []interface{}{5, 6})
t.Assert(array1.Slice(), []interface{}{2, 3, 4})
t.Assert(array1.PopRights(20), []interface{}{2, 3, 4})
t.Assert(array1.Slice(), []interface{}{})
t.Assert(array2.PopLefts(20), []interface{}{0, 1, 2, 3, 4, 5, 6})
t.Assert(array2.Slice(), []interface{}{})
})
}
func TestArray_Range(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
value1 := []interface{}{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewArrayFrom(value1)
array2 := garray.NewArrayFrom(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(10, 2), nil)
gtest.Assert(array2.Range(1, 3), []interface{}{1, 2})
t.Assert(array1.Range(0, 1), []interface{}{0})
t.Assert(array1.Range(1, 2), []interface{}{1})
t.Assert(array1.Range(0, 2), []interface{}{0, 1})
t.Assert(array1.Range(-1, 10), value1)
t.Assert(array1.Range(10, 2), nil)
t.Assert(array2.Range(1, 3), []interface{}{1, 2})
})
}
func TestArray_Merge(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
func1 := func(v1, v2 interface{}) int {
if gconv.Int(v1) < gconv.Int(v2) {
return 0
@ -147,7 +199,7 @@ func TestArray_Merge(t *testing.T) {
i2 := []interface{}{4, 5, 6, 7}
array1 := garray.NewArrayFrom(i1)
array2 := garray.NewArrayFrom(i2)
gtest.Assert(array1.Merge(array2).Slice(), []interface{}{0, 1, 2, 3, 4, 5, 6, 7})
t.Assert(array1.Merge(array2).Slice(), []interface{}{0, 1, 2, 3, 4, 5, 6, 7})
//s1 := []string{"a", "b", "c", "d"}
s2 := []string{"e", "f"}
@ -159,185 +211,192 @@ func TestArray_Merge(t *testing.T) {
s6 := garray.NewSortedIntArrayFrom([]int{1, 2, 3})
a1 := garray.NewArrayFrom(i1)
gtest.Assert(a1.Merge(s2).Len(), 6)
gtest.Assert(a1.Merge(i3).Len(), 9)
gtest.Assert(a1.Merge(i4).Len(), 10)
gtest.Assert(a1.Merge(s3).Len(), 12)
gtest.Assert(a1.Merge(s4).Len(), 14)
gtest.Assert(a1.Merge(s5).Len(), 16)
gtest.Assert(a1.Merge(s6).Len(), 19)
t.Assert(a1.Merge(s2).Len(), 6)
t.Assert(a1.Merge(i3).Len(), 9)
t.Assert(a1.Merge(i4).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 TestArray_Fill(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0}
a2 := []interface{}{0}
array1 := garray.NewArrayFrom(a1)
array2 := garray.NewArrayFrom(a2, true)
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})
t.Assert(array1.Fill(1, 2, 100), nil)
t.Assert(array1.Slice(), []interface{}{0, 100, 100})
t.Assert(array2.Fill(0, 2, 100), nil)
t.Assert(array2.Slice(), []interface{}{100, 100})
t.AssertNE(array2.Fill(-1, 2, 100), nil)
t.Assert(array2.Slice(), []interface{}{100, 100})
})
}
func TestArray_Chunk(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{1, 2, 3, 4, 5}
array1 := garray.NewArrayFrom(a1)
chunks := array1.Chunk(2)
gtest.Assert(len(chunks), 3)
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)
t.Assert(len(chunks), 3)
t.Assert(chunks[0], []interface{}{1, 2})
t.Assert(chunks[1], []interface{}{3, 4})
t.Assert(chunks[2], []interface{}{5})
t.Assert(array1.Chunk(0), nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{1, 2, 3, 4, 5}
array1 := garray.NewArrayFrom(a1)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []interface{}{1, 2, 3})
gtest.Assert(chunks[1], []interface{}{4, 5})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 2)
t.Assert(chunks[0], []interface{}{1, 2, 3})
t.Assert(chunks[1], []interface{}{4, 5})
t.Assert(array1.Chunk(0), nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{1, 2, 3, 4, 5, 6}
array1 := garray.NewArrayFrom(a1)
chunks := array1.Chunk(2)
gtest.Assert(len(chunks), 3)
gtest.Assert(chunks[0], []interface{}{1, 2})
gtest.Assert(chunks[1], []interface{}{3, 4})
gtest.Assert(chunks[2], []interface{}{5, 6})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 3)
t.Assert(chunks[0], []interface{}{1, 2})
t.Assert(chunks[1], []interface{}{3, 4})
t.Assert(chunks[2], []interface{}{5, 6})
t.Assert(array1.Chunk(0), nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{1, 2, 3, 4, 5, 6}
array1 := garray.NewArrayFrom(a1)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []interface{}{1, 2, 3})
gtest.Assert(chunks[1], []interface{}{4, 5, 6})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 2)
t.Assert(chunks[0], []interface{}{1, 2, 3})
t.Assert(chunks[1], []interface{}{4, 5, 6})
t.Assert(array1.Chunk(0), nil)
})
}
func TestArray_Pad(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0}
array1 := garray.NewArrayFrom(a1)
gtest.Assert(array1.Pad(3, 1).Slice(), []interface{}{0, 1, 1})
gtest.Assert(array1.Pad(-4, 1).Slice(), []interface{}{1, 0, 1, 1})
gtest.Assert(array1.Pad(3, 1).Slice(), []interface{}{1, 0, 1, 1})
t.Assert(array1.Pad(3, 1).Slice(), []interface{}{0, 1, 1})
t.Assert(array1.Pad(-4, 1).Slice(), []interface{}{1, 0, 1, 1})
t.Assert(array1.Pad(3, 1).Slice(), []interface{}{1, 0, 1, 1})
})
}
func TestArray_SubSlice(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewArrayFrom(a1)
array2 := garray.NewArrayFrom(a1, true)
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(9, 1), nil)
gtest.Assert(array1.SubSlice(-2, 2), []interface{}{5, 6})
gtest.Assert(array1.SubSlice(-9, 2), nil)
gtest.Assert(array1.SubSlice(1, -2), nil)
gtest.Assert(array2.SubSlice(0, 2), []interface{}{0, 1})
t.Assert(array1.SubSlice(0, 2), []interface{}{0, 1})
t.Assert(array1.SubSlice(2, 2), []interface{}{2, 3})
t.Assert(array1.SubSlice(5, 8), []interface{}{5, 6})
t.Assert(array1.SubSlice(9, 1), nil)
t.Assert(array1.SubSlice(-2, 2), []interface{}{5, 6})
t.Assert(array1.SubSlice(-9, 2), nil)
t.Assert(array1.SubSlice(1, -2), nil)
t.Assert(array2.SubSlice(0, 2), []interface{}{0, 1})
})
}
func TestArray_Rand(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewArrayFrom(a1)
gtest.Assert(len(array1.Rands(2)), 2)
gtest.Assert(len(array1.Rands(10)), 7)
gtest.AssertIN(array1.Rands(1)[0], a1)
t.Assert(len(array1.Rands(2)), 2)
t.Assert(len(array1.Rands(10)), 10)
t.AssertIN(array1.Rands(1)[0], a1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []interface{}{"a", "b", "c", "d"}
a1 := garray.NewArrayFrom(s1)
i1 := a1.Rand()
gtest.Assert(a1.Contains(i1), true)
gtest.Assert(a1.Len(), 4)
i1, ok := a1.Rand()
t.Assert(ok, true)
t.Assert(a1.Contains(i1), true)
t.Assert(a1.Len(), 4)
})
}
func TestArray_Shuffle(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewArrayFrom(a1)
gtest.Assert(array1.Shuffle().Len(), 7)
t.Assert(array1.Shuffle().Len(), 7)
})
}
func TestArray_Reverse(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewArrayFrom(a1)
gtest.Assert(array1.Reverse().Slice(), []interface{}{6, 5, 4, 3, 2, 1, 0})
t.Assert(array1.Reverse().Slice(), []interface{}{6, 5, 4, 3, 2, 1, 0})
})
}
func TestArray_Join(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewArrayFrom(a1)
gtest.Assert(array1.Join("."), `0.1.2.3.4.5.6`)
t.Assert(array1.Join("."), `0.1.2.3.4.5.6`)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, `"a"`, `\a`}
array1 := garray.NewArrayFrom(a1)
gtest.Assert(array1.Join("."), `0.1."a".\a`)
t.Assert(array1.Join("."), `0.1."a".\a`)
})
}
func TestArray_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewArrayFrom(a1)
gtest.Assert(array1.String(), `[0,1,2,3,4,5,6]`)
t.Assert(array1.String(), `[0,1,2,3,4,5,6]`)
})
}
func TestArray_Replace(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, 2, 3, 4, 5, 6}
a2 := []interface{}{"a", "b", "c"}
a3 := []interface{}{"m", "n", "p", "z", "x", "y", "d", "u"}
array1 := garray.NewArrayFrom(a1)
array2 := array1.Replace(a2)
gtest.Assert(array2.Len(), 7)
gtest.Assert(array2.Contains("b"), true)
gtest.Assert(array2.Contains(4), true)
gtest.Assert(array2.Contains("v"), false)
t.Assert(array2.Len(), 7)
t.Assert(array2.Contains("b"), true)
t.Assert(array2.Contains(4), true)
t.Assert(array2.Contains("v"), false)
array3 := array1.Replace(a3)
gtest.Assert(array3.Len(), 7)
gtest.Assert(array3.Contains(4), false)
gtest.Assert(array3.Contains("p"), true)
gtest.Assert(array3.Contains("u"), false)
t.Assert(array3.Len(), 7)
t.Assert(array3.Contains(4), false)
t.Assert(array3.Contains("p"), true)
t.Assert(array3.Contains("u"), false)
})
}
func TestArray_SetArray(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, 2, 3, 4, 5, 6}
a2 := []interface{}{"a", "b", "c"}
array1 := garray.NewArrayFrom(a1)
array1 = array1.SetArray(a2)
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1.Contains("b"), true)
gtest.Assert(array1.Contains("5"), false)
t.Assert(array1.Len(), 3)
t.Assert(array1.Contains("b"), true)
t.Assert(array1.Contains("5"), false)
})
}
func TestArray_Sum(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, 2, 3}
a2 := []interface{}{"a", "b", "c"}
a3 := []interface{}{"a", "1", "2"}
@ -346,39 +405,39 @@ func TestArray_Sum(t *testing.T) {
array2 := garray.NewArrayFrom(a2)
array3 := garray.NewArrayFrom(a3)
gtest.Assert(array1.Sum(), 6)
gtest.Assert(array2.Sum(), 0)
gtest.Assert(array3.Sum(), 3)
t.Assert(array1.Sum(), 6)
t.Assert(array2.Sum(), 0)
t.Assert(array3.Sum(), 3)
})
}
func TestArray_Clone(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, 2, 3}
array1 := garray.NewArrayFrom(a1)
array2 := array1.Clone()
gtest.Assert(array1.Len(), 4)
gtest.Assert(array2.Sum(), 6)
gtest.AssertEQ(array1, array2)
t.Assert(array1.Len(), 4)
t.Assert(array2.Sum(), 6)
t.AssertEQ(array1, array2)
})
}
func TestArray_CountValues(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "b", "c", "d", "e", "d"}
array1 := garray.NewArrayFrom(a1)
array2 := array1.CountValues()
gtest.Assert(len(array2), 5)
gtest.Assert(array2["b"], 1)
gtest.Assert(array2["d"], 2)
t.Assert(len(array2), 5)
t.Assert(array2["b"], 1)
t.Assert(array2["d"], 2)
})
}
func TestArray_LockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []interface{}{"a", "b", "c", "d"}
a1 := garray.NewArrayFrom(s1, true)
@ -404,13 +463,13 @@ func TestArray_LockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
gtest.Assert(a1.Contains("g"), true)
t.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
t.Assert(a1.Contains("g"), true)
})
}
func TestArray_RLockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []interface{}{"a", "b", "c", "d"}
a1 := garray.NewArrayFrom(s1, true)
@ -436,32 +495,32 @@ func TestArray_RLockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候并没有阻塞。
gtest.Assert(a1.Contains("g"), true)
t.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候并没有阻塞。
t.Assert(a1.Contains("g"), true)
})
}
func TestArray_Json(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []interface{}{"a", "b", "d", "c"}
a1 := garray.NewArrayFrom(s1)
b1, err1 := json.Marshal(a1)
b2, err2 := json.Marshal(s1)
gtest.Assert(b1, b2)
gtest.Assert(err1, err2)
t.Assert(b1, b2)
t.Assert(err1, err2)
a2 := garray.New()
err2 = json.Unmarshal(b2, &a2)
gtest.Assert(err2, nil)
gtest.Assert(a2.Slice(), s1)
t.Assert(err2, nil)
t.Assert(a2.Slice(), s1)
var a3 garray.Array
err := json.Unmarshal(b2, &a3)
gtest.Assert(err, nil)
gtest.Assert(a3.Slice(), s1)
t.Assert(err, nil)
t.Assert(a3.Slice(), s1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
type User struct {
Name string
Scores *garray.Array
@ -471,123 +530,123 @@ func TestArray_Json(t *testing.T) {
"Scores": []int{99, 100, 98},
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
user := new(User)
err = json.Unmarshal(b, user)
gtest.Assert(err, nil)
gtest.Assert(user.Name, data["Name"])
gtest.Assert(user.Scores, data["Scores"])
t.Assert(err, nil)
t.Assert(user.Name, data["Name"])
t.Assert(user.Scores, data["Scores"])
})
}
func TestArray_Iterator(t *testing.T) {
slice := g.Slice{"a", "b", "d", "c"}
array := garray.NewArrayFrom(slice)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.Iterator(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorAsc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorDesc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.Iterator(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorAsc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorDesc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
}
func TestArray_RemoveValue(t *testing.T) {
slice := g.Slice{"a", "b", "d", "c"}
array := garray.NewArrayFrom(slice)
gtest.Case(t, func() {
gtest.Assert(array.RemoveValue("e"), false)
gtest.Assert(array.RemoveValue("b"), true)
gtest.Assert(array.RemoveValue("a"), true)
gtest.Assert(array.RemoveValue("c"), true)
gtest.Assert(array.RemoveValue("f"), false)
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 TestArray_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Array *garray.Array
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`[1,2,3]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": g.Slice{1, 2, 3},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
})
}
func TestArray_FilterNil(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
values := g.Slice{0, 1, 2, 3, 4, "", g.Slice{}}
array := garray.NewArrayFromCopy(values)
gtest.Assert(array.FilterNil().Slice(), values)
t.Assert(array.FilterNil().Slice(), values)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewArrayFromCopy(g.Slice{nil, 1, 2, 3, 4, nil})
gtest.Assert(array.FilterNil(), g.Slice{1, 2, 3, 4})
t.Assert(array.FilterNil(), g.Slice{1, 2, 3, 4})
})
}
func TestArray_FilterEmpty(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewArrayFrom(g.Slice{0, 1, 2, 3, 4, "", g.Slice{}})
gtest.Assert(array.FilterEmpty(), g.Slice{1, 2, 3, 4})
t.Assert(array.FilterEmpty(), g.Slice{1, 2, 3, 4})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewArrayFrom(g.Slice{1, 2, 3, 4})
gtest.Assert(array.FilterEmpty(), g.Slice{1, 2, 3, 4})
t.Assert(array.FilterEmpty(), g.Slice{1, 2, 3, 4})
})
}

View File

@ -21,37 +21,54 @@ import (
)
func Test_IntArray_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
expect := []int{0, 1, 2, 3}
expect2 := []int{}
array := garray.NewIntArrayFrom(expect)
array2 := garray.NewIntArrayFrom(expect2)
gtest.Assert(array.Slice(), expect)
gtest.Assert(array.Interfaces(), expect)
t.Assert(array.Slice(), expect)
t.Assert(array.Interfaces(), 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.Remove(-1), 0)
gtest.Assert(array.Remove(100000), 0)
gtest.Assert(array.Contains(100), false)
v, ok := array.Get(0)
t.Assert(v, 100)
t.Assert(ok, true)
v, ok = array.Get(1)
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array.Search(100), 0)
t.Assert(array2.Search(100), -1)
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, 0)
t.Assert(ok, false)
v, ok = array.Remove(100000)
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.Contains(100), false)
array.Append(4)
gtest.Assert(array.Len(), 4)
t.Assert(array.Len(), 4)
array.InsertBefore(0, 100)
array.InsertAfter(0, 200)
gtest.Assert(array.Slice(), []int{100, 200, 1, 2, 3, 4})
t.Assert(array.Slice(), []int{100, 200, 1, 2, 3, 4})
array.InsertBefore(5, 300)
array.InsertAfter(6, 400)
gtest.Assert(array.Slice(), []int{100, 200, 1, 2, 3, 300, 4, 400})
gtest.Assert(array.Clear().Len(), 0)
t.Assert(array.Slice(), []int{100, 200, 1, 2, 3, 300, 4, 400})
t.Assert(array.Clear().Len(), 0)
})
}
func TestIntArray_Sort(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
expect1 := []int{0, 1, 2, 3}
expect2 := []int{3, 2, 1, 0}
array := garray.NewIntArray()
@ -61,69 +78,108 @@ func TestIntArray_Sort(t *testing.T) {
array2.Append(i)
}
array.Sort()
gtest.Assert(array.Slice(), expect1)
t.Assert(array.Slice(), expect1)
array.Sort(true)
gtest.Assert(array.Slice(), expect2)
gtest.Assert(array2.Slice(), expect2)
t.Assert(array.Slice(), expect2)
t.Assert(array2.Slice(), expect2)
})
}
func TestIntArray_Unique(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
expect := []int{1, 1, 2, 3}
array := garray.NewIntArrayFrom(expect)
gtest.Assert(array.Unique().Slice(), []int{1, 2, 3})
t.Assert(array.Unique().Slice(), []int{1, 2, 3})
})
}
func TestIntArray_PushAndPop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
expect := []int{0, 1, 2, 3}
array := garray.NewIntArrayFrom(expect)
gtest.Assert(array.Slice(), expect)
gtest.Assert(array.PopLeft(), 0)
gtest.Assert(array.PopRight(), 3)
gtest.AssertIN(array.PopRand(), []int{1, 2})
gtest.AssertIN(array.PopRand(), []int{1, 2})
gtest.Assert(array.Len(), 0)
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, []int{1, 2})
t.Assert(ok, true)
v, ok = array.PopRand()
t.AssertIN(v, []int{1, 2})
t.Assert(ok, true)
v, ok = array.PopRand()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.Len(), 0)
array.PushLeft(1).PushRight(2)
gtest.Assert(array.Slice(), []int{1, 2})
t.Assert(array.Slice(), []int{1, 2})
})
}
func TestIntArray_PopLeftsAndPopRights(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewIntArray()
v, ok := array.PopLeft()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopLefts(10), nil)
v, ok = array.PopRight()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopRights(10), nil)
v, ok = array.PopRand()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopRands(10), nil)
})
gtest.C(t, func(t *gtest.T) {
value1 := []int{0, 1, 2, 3, 4, 5, 6}
value2 := []int{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewIntArrayFrom(value1)
array2 := garray.NewIntArrayFrom(value2)
gtest.Assert(array1.PopLefts(2), []int{0, 1})
gtest.Assert(array1.Slice(), []int{2, 3, 4, 5, 6})
gtest.Assert(array1.PopRights(2), []int{5, 6})
gtest.Assert(array1.Slice(), []int{2, 3, 4})
gtest.Assert(array1.PopRights(20), []int{2, 3, 4})
gtest.Assert(array1.Slice(), []int{})
gtest.Assert(array2.PopLefts(20), []int{0, 1, 2, 3, 4, 5, 6})
gtest.Assert(array2.Slice(), []int{})
t.Assert(array1.PopLefts(2), []int{0, 1})
t.Assert(array1.Slice(), []int{2, 3, 4, 5, 6})
t.Assert(array1.PopRights(2), []int{5, 6})
t.Assert(array1.Slice(), []int{2, 3, 4})
t.Assert(array1.PopRights(20), []int{2, 3, 4})
t.Assert(array1.Slice(), []int{})
t.Assert(array2.PopLefts(20), []int{0, 1, 2, 3, 4, 5, 6})
t.Assert(array2.Slice(), []int{})
})
}
func TestIntArray_Range(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
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(array2.Range(1, 2), []int{1})
t.Assert(array1.Range(0, 1), []int{0})
t.Assert(array1.Range(1, 2), []int{1})
t.Assert(array1.Range(0, 2), []int{0, 1})
t.Assert(array1.Range(10, 2), nil)
t.Assert(array1.Range(-1, 10), value1)
t.Assert(array2.Range(1, 2), []int{1})
})
}
func TestIntArray_Merge(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
func1 := func(v1, v2 interface{}) int {
if gconv.Int(v1) < gconv.Int(v2) {
return 0
@ -147,260 +203,273 @@ func TestIntArray_Merge(t *testing.T) {
a7 := garray.NewSortedStrArrayFrom(s1)
a8 := garray.NewSortedArrayFrom([]interface{}{4, 5}, func1)
gtest.Assert(a1.Merge(a2).Slice(), []int{0, 1, 2, 3, 4, 5, 6, 7})
gtest.Assert(a1.Merge(a3).Len(), 10)
gtest.Assert(a1.Merge(a4).Len(), 13)
gtest.Assert(a1.Merge(a5).Len(), 15)
gtest.Assert(a1.Merge(a6).Len(), 18)
gtest.Assert(a1.Merge(a7).Len(), 21)
gtest.Assert(a1.Merge(a8).Len(), 23)
t.Assert(a1.Merge(a2).Slice(), []int{0, 1, 2, 3, 4, 5, 6, 7})
t.Assert(a1.Merge(a3).Len(), 10)
t.Assert(a1.Merge(a4).Len(), 13)
t.Assert(a1.Merge(a5).Len(), 15)
t.Assert(a1.Merge(a6).Len(), 18)
t.Assert(a1.Merge(a7).Len(), 21)
t.Assert(a1.Merge(a8).Len(), 23)
})
}
func TestIntArray_Fill(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{0}
a2 := []int{0}
array1 := garray.NewIntArrayFrom(a1)
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})
t.Assert(array1.Fill(1, 2, 100), nil)
t.Assert(array1.Slice(), []int{0, 100, 100})
t.Assert(array2.Fill(0, 2, 100), nil)
t.Assert(array2.Slice(), []int{100, 100})
t.AssertNE(array2.Fill(-1, 2, 100), nil)
t.Assert(array2.Slice(), []int{100, 100})
})
}
func TestIntArray_Chunk(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5}
array1 := garray.NewIntArrayFrom(a1)
chunks := array1.Chunk(2)
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})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 3)
t.Assert(chunks[0], []int{1, 2})
t.Assert(chunks[1], []int{3, 4})
t.Assert(chunks[2], []int{5})
t.Assert(array1.Chunk(0), nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5}
array1 := garray.NewIntArrayFrom(a1)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []int{1, 2, 3})
gtest.Assert(chunks[1], []int{4, 5})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 2)
t.Assert(chunks[0], []int{1, 2, 3})
t.Assert(chunks[1], []int{4, 5})
t.Assert(array1.Chunk(0), nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5, 6}
array1 := garray.NewIntArrayFrom(a1)
chunks := array1.Chunk(2)
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, 6})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 3)
t.Assert(chunks[0], []int{1, 2})
t.Assert(chunks[1], []int{3, 4})
t.Assert(chunks[2], []int{5, 6})
t.Assert(array1.Chunk(0), nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5, 6}
array1 := garray.NewIntArrayFrom(a1)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []int{1, 2, 3})
gtest.Assert(chunks[1], []int{4, 5, 6})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 2)
t.Assert(chunks[0], []int{1, 2, 3})
t.Assert(chunks[1], []int{4, 5, 6})
t.Assert(array1.Chunk(0), nil)
})
}
func TestIntArray_Pad(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{0}
array1 := garray.NewIntArrayFrom(a1)
gtest.Assert(array1.Pad(3, 1).Slice(), []int{0, 1, 1})
gtest.Assert(array1.Pad(-4, 1).Slice(), []int{1, 0, 1, 1})
gtest.Assert(array1.Pad(3, 1).Slice(), []int{1, 0, 1, 1})
t.Assert(array1.Pad(3, 1).Slice(), []int{0, 1, 1})
t.Assert(array1.Pad(-4, 1).Slice(), []int{1, 0, 1, 1})
t.Assert(array1.Pad(3, 1).Slice(), []int{1, 0, 1, 1})
})
}
func TestIntArray_SubSlice(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
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)
gtest.Assert(array1.SubSlice(0, 2), []int{0, 1})
gtest.Assert(array1.SubSlice(2, 2), []int{2, 3})
gtest.Assert(array1.SubSlice(5, 8), []int{5, 6})
gtest.Assert(array1.SubSlice(-1, 1), []int{6})
gtest.Assert(array1.SubSlice(-1, 9), []int{6})
gtest.Assert(array1.SubSlice(-2, 3), []int{5, 6})
gtest.Assert(array1.SubSlice(-7, 3), []int{0, 1, 2})
gtest.Assert(array1.SubSlice(-8, 3), nil)
gtest.Assert(array1.SubSlice(-1, -3), []int{3, 4, 5})
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(0, 2), []int{0, 1})
t.Assert(array1.SubSlice(6), []int{6})
t.Assert(array1.SubSlice(5), []int{5, 6})
t.Assert(array1.SubSlice(8), nil)
t.Assert(array1.SubSlice(0, 2), []int{0, 1})
t.Assert(array1.SubSlice(2, 2), []int{2, 3})
t.Assert(array1.SubSlice(5, 8), []int{5, 6})
t.Assert(array1.SubSlice(-1, 1), []int{6})
t.Assert(array1.SubSlice(-1, 9), []int{6})
t.Assert(array1.SubSlice(-2, 3), []int{5, 6})
t.Assert(array1.SubSlice(-7, 3), []int{0, 1, 2})
t.Assert(array1.SubSlice(-8, 3), nil)
t.Assert(array1.SubSlice(-1, -3), []int{3, 4, 5})
t.Assert(array1.SubSlice(-9, 3), nil)
t.Assert(array1.SubSlice(1, -1), []int{0})
t.Assert(array1.SubSlice(1, -3), nil)
t.Assert(array2.SubSlice(0, 2), []int{0, 1})
})
}
func TestIntArray_Rand(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewIntArrayFrom(a1)
gtest.Assert(len(array1.Rands(2)), 2)
gtest.Assert(len(array1.Rands(10)), 7)
gtest.AssertIN(array1.Rands(1)[0], a1)
gtest.AssertIN(array1.Rand(), 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.AssertIN(v, a1)
t.Assert(ok, true)
})
}
func TestIntArray_PopRands(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{100, 200, 300, 400, 500, 600}
array := garray.NewIntArrayFrom(a1)
ns1 := array.PopRands(2)
gtest.AssertIN(ns1, []int{100, 200, 300, 400, 500, 600})
gtest.Assert(len(ns1), 2)
t.AssertIN(ns1, []int{100, 200, 300, 400, 500, 600})
t.Assert(len(ns1), 2)
ns2 := array.PopRands(7)
gtest.Assert(len(ns2), 4)
gtest.AssertIN(ns2, []int{100, 200, 300, 400, 500, 600})
t.Assert(len(ns2), 4)
t.AssertIN(ns2, []int{100, 200, 300, 400, 500, 600})
})
}
func TestIntArray_Shuffle(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewIntArrayFrom(a1)
gtest.Assert(array1.Shuffle().Len(), 7)
t.Assert(array1.Shuffle().Len(), 7)
})
}
func TestIntArray_Reverse(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewIntArrayFrom(a1)
gtest.Assert(array1.Reverse().Slice(), []int{6, 5, 4, 3, 2, 1, 0})
t.Assert(array1.Reverse().Slice(), []int{6, 5, 4, 3, 2, 1, 0})
})
}
func TestIntArray_Join(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewIntArrayFrom(a1)
gtest.Assert(array1.Join("."), "0.1.2.3.4.5.6")
t.Assert(array1.Join("."), "0.1.2.3.4.5.6")
})
}
func TestIntArray_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{0, 1, 2, 3, 4, 5, 6}
array1 := garray.NewIntArrayFrom(a1)
gtest.Assert(array1.String(), "[0,1,2,3,4,5,6]")
t.Assert(array1.String(), "[0,1,2,3,4,5,6]")
})
}
func TestIntArray_SetArray(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 5}
a2 := []int{6, 7}
array1 := garray.NewIntArrayFrom(a1)
array1.SetArray(a2)
gtest.Assert(array1.Len(), 2)
gtest.Assert(array1, []int{6, 7})
t.Assert(array1.Len(), 2)
t.Assert(array1, []int{6, 7})
})
}
func TestIntArray_Replace(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 5}
a2 := []int{6, 7}
a3 := []int{9, 10, 11, 12, 13}
array1 := garray.NewIntArrayFrom(a1)
array1.Replace(a2)
gtest.Assert(array1, []int{6, 7, 3, 5})
t.Assert(array1, []int{6, 7, 3, 5})
array1.Replace(a3)
gtest.Assert(array1, []int{9, 10, 11, 12})
t.Assert(array1, []int{9, 10, 11, 12})
})
}
func TestIntArray_Clear(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 5}
array1 := garray.NewIntArrayFrom(a1)
array1.Clear()
gtest.Assert(array1.Len(), 0)
t.Assert(array1.Len(), 0)
})
}
func TestIntArray_Clone(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 5}
array1 := garray.NewIntArrayFrom(a1)
array2 := array1.Clone()
gtest.Assert(array1, array2)
t.Assert(array1, array2)
})
}
func TestArray_Get(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 5}
array1 := garray.NewIntArrayFrom(a1)
gtest.Assert(array1.Get(2), 3)
gtest.Assert(array1.Len(), 4)
v, ok := array1.Get(2)
t.Assert(v, 3)
t.Assert(ok, true)
t.Assert(array1.Len(), 4)
})
}
func TestIntArray_Sum(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 5}
array1 := garray.NewIntArrayFrom(a1)
gtest.Assert(array1.Sum(), 11)
t.Assert(array1.Sum(), 11)
})
}
func TestIntArray_CountValues(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 5, 3}
array1 := garray.NewIntArrayFrom(a1)
m1 := array1.CountValues()
gtest.Assert(len(m1), 4)
gtest.Assert(m1[1], 1)
gtest.Assert(m1[3], 2)
t.Assert(len(m1), 4)
t.Assert(m1[1], 1)
t.Assert(m1[3], 2)
})
}
func TestNewIntArrayFromCopy(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 5, 3}
array1 := garray.NewIntArrayFromCopy(a1)
gtest.Assert(array1.Len(), 5)
gtest.Assert(array1, a1)
t.Assert(array1.Len(), 5)
t.Assert(array1, a1)
})
}
func TestIntArray_Remove(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 5, 4}
array1 := garray.NewIntArrayFrom(a1)
n1 := array1.Remove(1)
gtest.Assert(n1, 2)
gtest.Assert(array1.Len(), 4)
v, ok := array1.Remove(1)
t.Assert(v, 2)
t.Assert(ok, true)
t.Assert(array1.Len(), 4)
n1 = array1.Remove(0)
gtest.Assert(n1, 1)
gtest.Assert(array1.Len(), 3)
v, ok = array1.Remove(0)
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array1.Len(), 3)
n1 = array1.Remove(2)
gtest.Assert(n1, 4)
gtest.Assert(array1.Len(), 2)
v, ok = array1.Remove(2)
t.Assert(v, 4)
t.Assert(ok, true)
t.Assert(array1.Len(), 2)
})
}
func TestIntArray_LockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []int{1, 2, 3, 4}
a1 := garray.NewIntArrayFrom(s1, true)
@ -426,26 +495,26 @@ func TestIntArray_LockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
gtest.Assert(a1.Contains(6), true)
t.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
t.Assert(a1.Contains(6), true)
})
}
func TestIntArray_SortFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []int{1, 4, 3, 2}
a1 := garray.NewIntArrayFrom(s1)
func1 := func(v1, v2 int) bool {
return v1 < v2
}
a11 := a1.SortFunc(func1)
gtest.Assert(a11, []int{1, 2, 3, 4})
t.Assert(a11, []int{1, 2, 3, 4})
})
}
func TestIntArray_RLockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []int{1, 2, 3, 4}
a1 := garray.NewIntArrayFrom(s1, true)
@ -471,31 +540,31 @@ func TestIntArray_RLockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候并没有阻塞。
gtest.Assert(a1.Contains(6), true)
t.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候并没有阻塞。
t.Assert(a1.Contains(6), true)
})
}
func TestIntArray_Json(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []int{1, 4, 3, 2}
a1 := garray.NewIntArrayFrom(s1)
b1, err1 := json.Marshal(a1)
b2, err2 := json.Marshal(s1)
gtest.Assert(b1, b2)
gtest.Assert(err1, err2)
t.Assert(b1, b2)
t.Assert(err1, err2)
a2 := garray.NewIntArray()
err1 = json.Unmarshal(b2, &a2)
gtest.Assert(a2.Slice(), s1)
t.Assert(a2.Slice(), s1)
var a3 garray.IntArray
err := json.Unmarshal(b2, &a3)
gtest.Assert(err, nil)
gtest.Assert(a3.Slice(), s1)
t.Assert(err, nil)
t.Assert(a3.Slice(), s1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
type User struct {
Name string
Scores *garray.IntArray
@ -505,112 +574,112 @@ func TestIntArray_Json(t *testing.T) {
"Scores": []int{99, 100, 98},
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
user := new(User)
err = json.Unmarshal(b, user)
gtest.Assert(err, nil)
gtest.Assert(user.Name, data["Name"])
gtest.Assert(user.Scores, data["Scores"])
t.Assert(err, nil)
t.Assert(user.Name, data["Name"])
t.Assert(user.Scores, data["Scores"])
})
}
func TestIntArray_Iterator(t *testing.T) {
slice := g.SliceInt{10, 20, 30, 40}
array := garray.NewIntArrayFrom(slice)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.Iterator(func(k int, v int) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorAsc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorDesc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.Iterator(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorAsc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorDesc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
}
func TestIntArray_RemoveValue(t *testing.T) {
slice := g.SliceInt{10, 20, 30, 40}
array := garray.NewIntArrayFrom(slice)
gtest.Case(t, func() {
gtest.Assert(array.RemoveValue(99), false)
gtest.Assert(array.RemoveValue(20), true)
gtest.Assert(array.RemoveValue(10), true)
gtest.Assert(array.RemoveValue(20), false)
gtest.Assert(array.RemoveValue(88), false)
gtest.Assert(array.Len(), 2)
gtest.C(t, func(t *gtest.T) {
t.Assert(array.RemoveValue(99), false)
t.Assert(array.RemoveValue(20), true)
t.Assert(array.RemoveValue(10), true)
t.Assert(array.RemoveValue(20), false)
t.Assert(array.RemoveValue(88), false)
t.Assert(array.Len(), 2)
})
}
func TestIntArray_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Array *garray.IntArray
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`[1,2,3]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": g.Slice{1, 2, 3},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
})
}
func TestIntArray_FilterEmpty(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewIntArrayFrom(g.SliceInt{0, 1, 2, 3, 4, 0})
gtest.Assert(array.FilterEmpty(), g.SliceInt{1, 2, 3, 4})
t.Assert(array.FilterEmpty(), g.SliceInt{1, 2, 3, 4})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewIntArrayFrom(g.SliceInt{1, 2, 3, 4})
gtest.Assert(array.FilterEmpty(), g.SliceInt{1, 2, 3, 4})
t.Assert(array.FilterEmpty(), g.SliceInt{1, 2, 3, 4})
})
}

View File

@ -21,38 +21,51 @@ import (
)
func Test_StrArray_Basic(t *testing.T) {
gtest.Case(t, func() {
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{})
gtest.Assert(array.Slice(), expect)
gtest.Assert(array.Interfaces(), expect)
t.Assert(array.Slice(), expect)
t.Assert(array.Interfaces(), 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(array.Contains("100"), true)
gtest.Assert(array.Remove(0), 100)
gtest.Assert(array.Remove(-1), "")
gtest.Assert(array.Remove(100000), "")
gtest.Assert(array.Contains("100"), false)
v, ok := array.Get(0)
t.Assert(v, 100)
t.Assert(ok, true)
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")
gtest.Assert(array.Len(), 4)
t.Assert(array.Len(), 4)
array.InsertBefore(0, "100")
array.InsertAfter(0, "200")
gtest.Assert(array.Slice(), []string{"100", "200", "1", "2", "3", "4"})
t.Assert(array.Slice(), []string{"100", "200", "1", "2", "3", "4"})
array.InsertBefore(5, "300")
array.InsertAfter(6, "400")
gtest.Assert(array.Slice(), []string{"100", "200", "1", "2", "3", "300", "4", "400"})
gtest.Assert(array.Clear().Len(), 0)
gtest.Assert(array2.Slice(), expect)
gtest.Assert(array3.Search("100"), -1)
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)
})
}
func TestStrArray_Sort(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
expect1 := []string{"0", "1", "2", "3"}
expect2 := []string{"3", "2", "1", "0"}
array := garray.NewStrArray()
@ -60,73 +73,108 @@ func TestStrArray_Sort(t *testing.T) {
array.Append(gconv.String(i))
}
array.Sort()
gtest.Assert(array.Slice(), expect1)
t.Assert(array.Slice(), expect1)
array.Sort(true)
gtest.Assert(array.Slice(), expect2)
t.Assert(array.Slice(), expect2)
})
}
func TestStrArray_Unique(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
expect := []string{"1", "1", "2", "3"}
array := garray.NewStrArrayFrom(expect)
gtest.Assert(array.Unique().Slice(), []string{"1", "2", "3"})
t.Assert(array.Unique().Slice(), []string{"1", "2", "3"})
})
}
func TestStrArray_PushAndPop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
expect := []string{"0", "1", "2", "3"}
array := garray.NewStrArrayFrom(expect)
gtest.Assert(array.Slice(), expect)
gtest.Assert(array.PopLeft(), "0")
gtest.Assert(array.PopRight(), "3")
gtest.AssertIN(array.PopRand(), []string{"1", "2"})
gtest.AssertIN(array.PopRand(), []string{"1", "2"})
gtest.Assert(array.Len(), 0)
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")
gtest.Assert(array.Slice(), []string{"1", "2"})
t.Assert(array.Slice(), []string{"1", "2"})
})
}
func TestStrArray_PopLeftsAndPopRights(t *testing.T) {
gtest.Case(t, func() {
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)
gtest.Assert(array1.PopLefts(2), []interface{}{"0", "1"})
gtest.Assert(array1.Slice(), []interface{}{"2", "3", "4", "5", "6"})
gtest.Assert(array1.PopRights(2), []interface{}{"5", "6"})
gtest.Assert(array1.Slice(), []interface{}{"2", "3", "4"})
gtest.Assert(array1.PopRights(20), []interface{}{"2", "3", "4"})
gtest.Assert(array1.Slice(), []interface{}{})
gtest.Assert(array2.PopLefts(20), []interface{}{"0", "1", "2", "3", "4", "5", "6"})
gtest.Assert(array2.Slice(), []interface{}{})
t.Assert(array1.PopLefts(2), []interface{}{"0", "1"})
t.Assert(array1.Slice(), []interface{}{"2", "3", "4", "5", "6"})
t.Assert(array1.PopRights(2), []interface{}{"5", "6"})
t.Assert(array1.Slice(), []interface{}{"2", "3", "4"})
t.Assert(array1.PopRights(20), []interface{}{"2", "3", "4"})
t.Assert(array1.Slice(), []interface{}{})
t.Assert(array2.PopLefts(20), []interface{}{"0", "1", "2", "3", "4", "5", "6"})
t.Assert(array2.Slice(), []interface{}{})
})
}
func TestString_Range(t *testing.T) {
gtest.Case(t, func() {
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)
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(10, 1), nil)
gtest.Assert(array2.Range(0, 1), []interface{}{"0"})
t.Assert(array1.Range(0, 1), []interface{}{"0"})
t.Assert(array1.Range(1, 2), []interface{}{"1"})
t.Assert(array1.Range(0, 2), []interface{}{"0", "1"})
t.Assert(array1.Range(-1, 10), value1)
t.Assert(array1.Range(10, 1), nil)
t.Assert(array2.Range(0, 1), []interface{}{"0"})
})
}
func TestStrArray_Merge(t *testing.T) {
gtest.Case(t, func() {
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)
gtest.Assert(array1.Merge(array2).Slice(), []string{"0", "1", "2", "3", "4", "5", "6", "7"})
t.Assert(array1.Merge(array2).Slice(), []string{"0", "1", "2", "3", "4", "5", "6", "7"})
func1 := func(v1, v2 interface{}) int {
if gconv.Int(v1) < gconv.Int(v2) {
@ -145,267 +193,273 @@ func TestStrArray_Merge(t *testing.T) {
s6 := garray.NewSortedIntArrayFrom([]int{1, 2, 3})
a1 := garray.NewStrArrayFrom(s1)
gtest.Assert(a1.Merge(s2).Len(), 6)
gtest.Assert(a1.Merge(i1).Len(), 9)
gtest.Assert(a1.Merge(i2).Len(), 10)
gtest.Assert(a1.Merge(s3).Len(), 12)
gtest.Assert(a1.Merge(s4).Len(), 14)
gtest.Assert(a1.Merge(s5).Len(), 16)
gtest.Assert(a1.Merge(s6).Len(), 19)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0"}
a2 := []string{"0"}
array1 := garray.NewStrArrayFrom(a1)
array2 := garray.NewStrArrayFrom(a2)
gtest.Assert(array1.Fill(1, 2, "100").Slice(), []string{"0", "100", "100"})
gtest.Assert(array2.Fill(0, 2, "100").Slice(), []string{"100", "100"})
s1 := array2.Fill(-1, 2, "100")
gtest.Assert(s1.Len(), 2)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"1", "2", "3", "4", "5"}
array1 := garray.NewStrArrayFrom(a1)
chunks := array1.Chunk(2)
gtest.Assert(len(chunks), 3)
gtest.Assert(chunks[0], []string{"1", "2"})
gtest.Assert(chunks[1], []string{"3", "4"})
gtest.Assert(chunks[2], []string{"5"})
gtest.Assert(len(array1.Chunk(0)), 0)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"1", "2", "3", "4", "5"}
array1 := garray.NewStrArrayFrom(a1)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []string{"1", "2", "3"})
gtest.Assert(chunks[1], []string{"4", "5"})
gtest.Assert(array1.Chunk(0), nil)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
chunks := array1.Chunk(2)
gtest.Assert(len(chunks), 3)
gtest.Assert(chunks[0], []string{"1", "2"})
gtest.Assert(chunks[1], []string{"3", "4"})
gtest.Assert(chunks[2], []string{"5", "6"})
gtest.Assert(array1.Chunk(0), nil)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []string{"1", "2", "3"})
gtest.Assert(chunks[1], []string{"4", "5", "6"})
gtest.Assert(array1.Chunk(0), nil)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0"}
array1 := garray.NewStrArrayFrom(a1)
gtest.Assert(array1.Pad(3, "1").Slice(), []string{"0", "1", "1"})
gtest.Assert(array1.Pad(-4, "1").Slice(), []string{"1", "0", "1", "1"})
gtest.Assert(array1.Pad(3, "1").Slice(), []string{"1", "0", "1", "1"})
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.Case(t, func() {
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)
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, 2), nil)
gtest.Assert(array1.SubSlice(1, -2), nil)
gtest.Assert(array1.SubSlice(-5, 2), []string{"2", "3"})
gtest.Assert(array1.SubSlice(-10, 1), nil)
gtest.Assert(array2.SubSlice(0, 2), []string{"0", "1"})
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
gtest.Assert(len(array1.Rands(2)), "2")
gtest.Assert(len(array1.Rands(10)), "7")
gtest.AssertIN(array1.Rands(1)[0], a1)
gtest.Assert(len(array1.Rand()), 1)
gtest.AssertIN(array1.Rand(), 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)
})
}
func TestStrArray_PopRands(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"a", "b", "c", "d", "e", "f", "g"}
array1 := garray.NewStrArrayFrom(a1)
gtest.AssertIN(array1.PopRands(1), []string{"a", "b", "c", "d", "e", "f", "g"})
gtest.AssertIN(array1.PopRands(1), []string{"a", "b", "c", "d", "e", "f", "g"})
gtest.AssertNI(array1.PopRands(1), array1.Slice())
gtest.AssertNI(array1.PopRands(1), array1.Slice())
gtest.Assert(len(array1.PopRands(10)), 3)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
gtest.Assert(array1.Shuffle().Len(), 7)
t.Assert(array1.Shuffle().Len(), 7)
})
}
func TestStrArray_Reverse(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
gtest.Assert(array1.Reverse().Slice(), []string{"6", "5", "4", "3", "2", "1", "0"})
t.Assert(array1.Reverse().Slice(), []string{"6", "5", "4", "3", "2", "1", "0"})
})
}
func TestStrArray_Join(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
gtest.Assert(array1.Join("."), `0.1.2.3.4.5.6`)
t.Assert(array1.Join("."), `0.1.2.3.4.5.6`)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", `"a"`, `\a`}
array1 := garray.NewStrArrayFrom(a1)
gtest.Assert(array1.Join("."), `0.1."a".\a`)
t.Assert(array1.Join("."), `0.1."a".\a`)
})
}
func TestStrArray_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
gtest.Assert(array1.String(), `["0","1","2","3","4","5","6"]`)
t.Assert(array1.String(), `["0","1","2","3","4","5","6"]`)
})
}
func TestNewStrArrayFromCopy(t *testing.T) {
gtest.Case(t, func() {
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)
gtest.Assert(a2.Contains("1"), true)
gtest.Assert(a2.Len(), 7)
gtest.Assert(a2, a3)
t.Assert(a2.Contains("1"), true)
t.Assert(a2.Len(), 7)
t.Assert(a2, a3)
})
}
func TestStrArray_SetArray(t *testing.T) {
gtest.Case(t, func() {
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)
gtest.Assert(array1.Contains("2"), true)
gtest.Assert(array1.Len(), 7)
t.Assert(array1.Contains("2"), true)
t.Assert(array1.Len(), 7)
array1 = array1.SetArray(a2)
gtest.Assert(array1.Contains("2"), false)
gtest.Assert(array1.Contains("c"), true)
gtest.Assert(array1.Len(), 4)
t.Assert(array1.Contains("2"), false)
t.Assert(array1.Contains("c"), true)
t.Assert(array1.Len(), 4)
})
}
func TestStrArray_Replace(t *testing.T) {
gtest.Case(t, func() {
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)
gtest.Assert(array1.Contains("2"), true)
gtest.Assert(array1.Len(), 7)
t.Assert(array1.Contains("2"), true)
t.Assert(array1.Len(), 7)
array1 = array1.Replace(a2)
gtest.Assert(array1.Contains("2"), false)
gtest.Assert(array1.Contains("c"), true)
gtest.Assert(array1.Contains("5"), true)
gtest.Assert(array1.Len(), 7)
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)
gtest.Assert(array1.Contains("2"), false)
gtest.Assert(array1.Contains("c"), false)
gtest.Assert(array1.Contains("5"), false)
gtest.Assert(array1.Contains("p"), true)
gtest.Assert(array1.Contains("r"), false)
gtest.Assert(array1.Len(), 7)
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.Case(t, func() {
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)
gtest.Assert(array1.Sum(), 21)
gtest.Assert(array2.Sum(), 18)
t.Assert(array1.Sum(), 21)
t.Assert(array2.Sum(), 18)
})
}
func TestStrArray_PopRand(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
str1 := array1.PopRand()
gtest.Assert(strings.Contains("0,1,2,3,4,5,6", str1), true)
gtest.Assert(array1.Len(), 6)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "5", "6"}
array1 := garray.NewStrArrayFrom(a1)
array2 := array1.Clone()
gtest.Assert(array2, array1)
gtest.Assert(array2.Len(), 7)
t.Assert(array2, array1)
t.Assert(array2.Len(), 7)
})
}
func TestStrArray_CountValues(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"0", "1", "2", "3", "4", "4", "6"}
array1 := garray.NewStrArrayFrom(a1)
m1 := array1.CountValues()
gtest.Assert(len(m1), 6)
gtest.Assert(m1["2"], 1)
gtest.Assert(m1["4"], 2)
t.Assert(len(m1), 6)
t.Assert(m1["2"], 1)
t.Assert(m1["4"], 2)
})
}
func TestStrArray_Remove(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "a", "c"}
array1 := garray.NewStrArrayFrom(a1)
s1 := array1.Remove(1)
gtest.Assert(s1, "a")
gtest.Assert(array1.Len(), 4)
s1 = array1.Remove(3)
gtest.Assert(s1, "c")
gtest.Assert(array1.Len(), 3)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []string{"a", "b", "c", "d"}
a1 := garray.NewStrArrayFrom(s1, true)
@ -431,25 +485,25 @@ func TestStrArray_RLockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候并没有阻塞。
gtest.Assert(a1.Contains("g"), true)
t.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候并没有阻塞。
t.Assert(a1.Contains("g"), true)
})
}
func TestStrArray_SortFunc(t *testing.T) {
gtest.Case(t, func() {
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)
gtest.Assert(a11, []string{"a", "b", "c", "d"})
t.Assert(a11, []string{"a", "b", "c", "d"})
})
}
func TestStrArray_LockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []string{"a", "b", "c", "d"}
a1 := garray.NewStrArrayFrom(s1, true)
@ -475,31 +529,31 @@ func TestStrArray_LockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
gtest.Assert(a1.Contains("g"), true)
t.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
t.Assert(a1.Contains("g"), true)
})
}
func TestStrArray_Json(t *testing.T) {
gtest.Case(t, func() {
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)
gtest.Assert(b1, b2)
gtest.Assert(err1, err2)
t.Assert(b1, b2)
t.Assert(err1, err2)
a2 := garray.NewStrArray()
err1 = json.Unmarshal(b2, &a2)
gtest.Assert(a2.Slice(), s1)
t.Assert(a2.Slice(), s1)
var a3 garray.StrArray
err := json.Unmarshal(b2, &a3)
gtest.Assert(err, nil)
gtest.Assert(a3.Slice(), s1)
t.Assert(err, nil)
t.Assert(a3.Slice(), s1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
type User struct {
Name string
Scores *garray.StrArray
@ -509,111 +563,111 @@ func TestStrArray_Json(t *testing.T) {
"Scores": []string{"A+", "A", "A"},
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
user := new(User)
err = json.Unmarshal(b, user)
gtest.Assert(err, nil)
gtest.Assert(user.Name, data["Name"])
gtest.Assert(user.Scores, data["Scores"])
t.Assert(err, nil)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.Iterator(func(k int, v string) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorAsc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorDesc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.Iterator(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorAsc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorDesc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
}
func TestStrArray_RemoveValue(t *testing.T) {
slice := g.SliceStr{"a", "b", "d", "c"}
array := garray.NewStrArrayFrom(slice)
gtest.Case(t, func() {
gtest.Assert(array.RemoveValue("e"), false)
gtest.Assert(array.RemoveValue("b"), true)
gtest.Assert(array.RemoveValue("a"), true)
gtest.Assert(array.RemoveValue("c"), true)
gtest.Assert(array.RemoveValue("f"), false)
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_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Array *garray.StrArray
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`["1","2","3"]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.SliceStr{"1", "2", "3"})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.SliceStr{"1", "2", "3"})
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": g.SliceStr{"1", "2", "3"},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.SliceStr{"1", "2", "3"})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.SliceStr{"1", "2", "3"})
})
}
func TestStrArray_FilterEmpty(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom(g.SliceStr{"", "1", "2", "0"})
gtest.Assert(array.FilterEmpty(), g.SliceStr{"1", "2", "0"})
t.Assert(array.FilterEmpty(), g.SliceStr{"1", "2", "0"})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewStrArrayFrom(g.SliceStr{"1", "2"})
gtest.Assert(array.FilterEmpty(), g.SliceStr{"1", "2"})
t.Assert(array.FilterEmpty(), g.SliceStr{"1", "2"})
})
}

View File

@ -22,7 +22,7 @@ import (
)
func TestSortedArray_NewSortedArrayFrom(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "f", "c"}
a2 := []interface{}{"h", "j", "i", "k"}
func1 := func(v1, v2 interface{}) int {
@ -34,16 +34,16 @@ func TestSortedArray_NewSortedArrayFrom(t *testing.T) {
array1 := garray.NewSortedArrayFrom(a1, func1)
array2 := garray.NewSortedArrayFrom(a2, func2)
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1, []interface{}{"a", "c", "f"})
t.Assert(array1.Len(), 3)
t.Assert(array1, []interface{}{"a", "c", "f"})
gtest.Assert(array2.Len(), 4)
gtest.Assert(array2, []interface{}{"k", "i", "j", "h"})
t.Assert(array2.Len(), 4)
t.Assert(array2, []interface{}{"k", "i", "j", "h"})
})
}
func TestNewSortedArrayFromCopy(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "f", "c"}
func1 := func(v1, v2 interface{}) int {
@ -54,15 +54,15 @@ func TestNewSortedArrayFromCopy(t *testing.T) {
}
array1 := garray.NewSortedArrayFromCopy(a1, func1)
array2 := garray.NewSortedArrayFromCopy(a1, func2)
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1, []interface{}{"a", "c", "f"})
gtest.Assert(array1.Len(), 3)
gtest.Assert(array2, []interface{}{"c", "f", "a"})
t.Assert(array1.Len(), 3)
t.Assert(array1, []interface{}{"a", "c", "f"})
t.Assert(array1.Len(), 3)
t.Assert(array2, []interface{}{"c", "f", "a"})
})
}
func TestSortedArray_SetArray(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "f", "c"}
a2 := []interface{}{"e", "h", "g", "k"}
@ -72,171 +72,207 @@ func TestSortedArray_SetArray(t *testing.T) {
array1 := garray.NewSortedArrayFrom(a1, func1)
array1.SetArray(a2)
gtest.Assert(array1.Len(), 4)
gtest.Assert(array1, []interface{}{"e", "g", "h", "k"})
t.Assert(array1.Len(), 4)
t.Assert(array1, []interface{}{"e", "g", "h", "k"})
})
}
func TestSortedArray_Sort(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "f", "c"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
array1.Sort()
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1, []interface{}{"a", "c", "f"})
t.Assert(array1.Len(), 3)
t.Assert(array1, []interface{}{"a", "c", "f"})
})
}
func TestSortedArray_Get(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "f", "c"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
gtest.Assert(array1.Get(2), "f")
gtest.Assert(array1.Get(1), "c")
v, ok := array1.Get(2)
t.Assert(v, "f")
t.Assert(ok, true)
v, ok = array1.Get(1)
t.Assert(v, "c")
t.Assert(ok, true)
})
}
func TestSortedArray_Remove(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.Remove(1)
gtest.Assert(gconv.String(i1), "b")
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1.Contains("b"), false)
i1, ok := array1.Remove(1)
t.Assert(ok, true)
t.Assert(gconv.String(i1), "b")
t.Assert(array1.Len(), 3)
t.Assert(array1.Contains("b"), false)
gtest.Assert(array1.Remove(-1), nil)
gtest.Assert(array1.Remove(100000), nil)
v, ok := array1.Remove(-1)
t.Assert(v, nil)
t.Assert(ok, false)
i2 := array1.Remove(0)
gtest.Assert(gconv.String(i2), "a")
gtest.Assert(array1.Len(), 2)
gtest.Assert(array1.Contains("a"), false)
v, ok = array1.Remove(100000)
t.Assert(v, nil)
t.Assert(ok, false)
i3 := array1.Remove(1)
gtest.Assert(gconv.String(i3), "d")
gtest.Assert(array1.Len(), 1)
gtest.Assert(array1.Contains("d"), false)
i2, ok := array1.Remove(0)
t.Assert(ok, true)
t.Assert(gconv.String(i2), "a")
t.Assert(array1.Len(), 2)
t.Assert(array1.Contains("a"), false)
i3, ok := array1.Remove(1)
t.Assert(ok, true)
t.Assert(gconv.String(i3), "d")
t.Assert(array1.Len(), 1)
t.Assert(array1.Contains("d"), false)
})
}
func TestSortedArray_PopLeft(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.PopLeft()
gtest.Assert(gconv.String(i1), "a")
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1, []interface{}{"b", "c", "d"})
i1, ok := array1.PopLeft()
t.Assert(ok, true)
t.Assert(gconv.String(i1), "a")
t.Assert(array1.Len(), 3)
t.Assert(array1, []interface{}{"b", "c", "d"})
})
}
func TestSortedArray_PopRight(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.PopRight()
gtest.Assert(gconv.String(i1), "d")
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1, []interface{}{"a", "b", "c"})
i1, ok := array1.PopRight()
t.Assert(ok, true)
t.Assert(gconv.String(i1), "d")
t.Assert(array1.Len(), 3)
t.Assert(array1, []interface{}{"a", "b", "c"})
})
}
func TestSortedArray_PopRand(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.PopRand()
gtest.AssertIN(i1, []interface{}{"a", "d", "c", "b"})
gtest.Assert(array1.Len(), 3)
i1, ok := array1.PopRand()
t.Assert(ok, true)
t.AssertIN(i1, []interface{}{"a", "d", "c", "b"})
t.Assert(array1.Len(), 3)
})
}
func TestSortedArray_PopRands(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.PopRands(2)
gtest.Assert(len(i1), 2)
gtest.AssertIN(i1, []interface{}{"a", "d", "c", "b"})
gtest.Assert(array1.Len(), 2)
t.Assert(len(i1), 2)
t.AssertIN(i1, []interface{}{"a", "d", "c", "b"})
t.Assert(array1.Len(), 2)
i2 := array1.PopRands(3)
gtest.Assert(len(i1), 2)
gtest.AssertIN(i2, []interface{}{"a", "d", "c", "b"})
gtest.Assert(array1.Len(), 0)
t.Assert(len(i1), 2)
t.AssertIN(i2, []interface{}{"a", "d", "c", "b"})
t.Assert(array1.Len(), 0)
})
}
func TestSortedArray_Empty(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedArray(gutil.ComparatorInt)
v, ok := array.PopLeft()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopLefts(10), nil)
v, ok = array.PopRight()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopRights(10), nil)
v, ok = array.PopRand()
t.Assert(v, nil)
t.Assert(ok, false)
t.Assert(array.PopRands(10), nil)
})
}
func TestSortedArray_PopLefts(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b", "e", "f"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.PopLefts(2)
gtest.Assert(len(i1), 2)
gtest.AssertIN(i1, []interface{}{"a", "d", "c", "b", "e", "f"})
gtest.Assert(array1.Len(), 4)
t.Assert(len(i1), 2)
t.AssertIN(i1, []interface{}{"a", "d", "c", "b", "e", "f"})
t.Assert(array1.Len(), 4)
i2 := array1.PopLefts(5)
gtest.Assert(len(i2), 4)
gtest.AssertIN(i1, []interface{}{"a", "d", "c", "b", "e", "f"})
gtest.Assert(array1.Len(), 0)
t.Assert(len(i2), 4)
t.AssertIN(i1, []interface{}{"a", "d", "c", "b", "e", "f"})
t.Assert(array1.Len(), 0)
})
}
func TestSortedArray_PopRights(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b", "e", "f"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.PopRights(2)
gtest.Assert(len(i1), 2)
gtest.Assert(i1, []interface{}{"e", "f"})
gtest.Assert(array1.Len(), 4)
t.Assert(len(i1), 2)
t.Assert(i1, []interface{}{"e", "f"})
t.Assert(array1.Len(), 4)
i2 := array1.PopRights(10)
gtest.Assert(len(i2), 4)
t.Assert(len(i2), 4)
})
}
func TestSortedArray_Range(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b", "e", "f"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
@ -244,25 +280,25 @@ func TestSortedArray_Range(t *testing.T) {
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)
t.Assert(i1, []interface{}{"c", "d", "e"})
t.Assert(array1.Len(), 6)
i2 := array1.Range(7, 5)
gtest.Assert(len(i2), 0)
t.Assert(len(i2), 0)
i2 = array1.Range(-1, 2)
gtest.Assert(i2, []interface{}{"a", "b"})
t.Assert(i2, []interface{}{"a", "b"})
i2 = array1.Range(4, 10)
gtest.Assert(len(i2), 2)
gtest.Assert(i2, []interface{}{"e", "f"})
t.Assert(len(i2), 2)
t.Assert(i2, []interface{}{"e", "f"})
gtest.Assert(array2.Range(1, 3), []interface{}{"b", "c"})
t.Assert(array2.Range(1, 3), []interface{}{"b", "c"})
})
}
func TestSortedArray_Sum(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b", "e", "f"}
a2 := []interface{}{"1", "2", "3", "b", "e", "f"}
a3 := []interface{}{"4", "5", "6"}
@ -272,15 +308,15 @@ func TestSortedArray_Sum(t *testing.T) {
array1 := garray.NewSortedArrayFrom(a1, func1)
array2 := garray.NewSortedArrayFrom(a2, func1)
array3 := garray.NewSortedArrayFrom(a3, func1)
gtest.Assert(array1.Sum(), 0)
gtest.Assert(array2.Sum(), 6)
gtest.Assert(array3.Sum(), 15)
t.Assert(array1.Sum(), 0)
t.Assert(array2.Sum(), 6)
t.Assert(array3.Sum(), 15)
})
}
func TestSortedArray_Clone(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b", "e", "f"}
func1 := func(v1, v2 interface{}) int {
@ -288,30 +324,30 @@ func TestSortedArray_Clone(t *testing.T) {
}
array1 := garray.NewSortedArrayFrom(a1, func1)
array2 := array1.Clone()
gtest.Assert(array1, array2)
t.Assert(array1, array2)
array1.Remove(1)
gtest.AssertNE(array1, array2)
t.AssertNE(array1, array2)
})
}
func TestSortedArray_Clear(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b", "e", "f"}
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
array1 := garray.NewSortedArrayFrom(a1, func1)
gtest.Assert(array1.Len(), 6)
t.Assert(array1.Len(), 6)
array1.Clear()
gtest.Assert(array1.Len(), 0)
t.Assert(array1.Len(), 0)
})
}
func TestSortedArray_Chunk(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b", "e"}
func1 := func(v1, v2 interface{}) int {
@ -319,45 +355,45 @@ func TestSortedArray_Chunk(t *testing.T) {
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.Chunk(2)
gtest.Assert(len(i1), 3)
gtest.Assert(i1[0], []interface{}{"a", "b"})
gtest.Assert(i1[2], []interface{}{"e"})
t.Assert(len(i1), 3)
t.Assert(i1[0], []interface{}{"a", "b"})
t.Assert(i1[2], []interface{}{"e"})
i1 = array1.Chunk(0)
gtest.Assert(len(i1), 0)
t.Assert(len(i1), 0)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{1, 2, 3, 4, 5}
array1 := garray.NewSortedArrayFrom(a1, gutil.ComparatorInt)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []interface{}{1, 2, 3})
gtest.Assert(chunks[1], []interface{}{4, 5})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 2)
t.Assert(chunks[0], []interface{}{1, 2, 3})
t.Assert(chunks[1], []interface{}{4, 5})
t.Assert(array1.Chunk(0), nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{1, 2, 3, 4, 5, 6}
array1 := garray.NewSortedArrayFrom(a1, gutil.ComparatorInt)
chunks := array1.Chunk(2)
gtest.Assert(len(chunks), 3)
gtest.Assert(chunks[0], []interface{}{1, 2})
gtest.Assert(chunks[1], []interface{}{3, 4})
gtest.Assert(chunks[2], []interface{}{5, 6})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 3)
t.Assert(chunks[0], []interface{}{1, 2})
t.Assert(chunks[1], []interface{}{3, 4})
t.Assert(chunks[2], []interface{}{5, 6})
t.Assert(array1.Chunk(0), nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{1, 2, 3, 4, 5, 6}
array1 := garray.NewSortedArrayFrom(a1, gutil.ComparatorInt)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []interface{}{1, 2, 3})
gtest.Assert(chunks[1], []interface{}{4, 5, 6})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 2)
t.Assert(chunks[0], []interface{}{1, 2, 3})
t.Assert(chunks[1], []interface{}{4, 5, 6})
t.Assert(array1.Chunk(0), nil)
})
}
func TestSortedArray_SubSlice(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "b", "e"}
func1 := func(v1, v2 interface{}) int {
@ -366,42 +402,43 @@ func TestSortedArray_SubSlice(t *testing.T) {
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"})
t.Assert(len(i1), 3)
t.Assert(i1, []interface{}{"c", "d", "e"})
i1 = array1.SubSlice(2, 6)
gtest.Assert(len(i1), 3)
gtest.Assert(i1, []interface{}{"c", "d", "e"})
t.Assert(len(i1), 3)
t.Assert(i1, []interface{}{"c", "d", "e"})
i1 = array1.SubSlice(7, 2)
gtest.Assert(len(i1), 0)
t.Assert(len(i1), 0)
s1 := array1.SubSlice(1, -2)
gtest.Assert(s1, nil)
t.Assert(s1, nil)
s1 = array1.SubSlice(-9, 2)
gtest.Assert(s1, nil)
gtest.Assert(array2.SubSlice(1, 3), []interface{}{"b", "c", "d"})
t.Assert(s1, nil)
t.Assert(array2.SubSlice(1, 3), []interface{}{"b", "c", "d"})
})
}
func TestSortedArray_Rand(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
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)
i1 := array1.Rand()
gtest.AssertIN(i1, []interface{}{"a", "d", "c"})
gtest.Assert(array1.Len(), 3)
i1, ok := array1.Rand()
t.Assert(ok, true)
t.AssertIN(i1, []interface{}{"a", "d", "c"})
t.Assert(array1.Len(), 3)
})
}
func TestSortedArray_Rands(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c"}
func1 := func(v1, v2 interface{}) int {
@ -409,43 +446,43 @@ func TestSortedArray_Rands(t *testing.T) {
}
array1 := garray.NewSortedArrayFrom(a1, func1)
i1 := array1.Rands(2)
gtest.AssertIN(i1, []interface{}{"a", "d", "c"})
gtest.Assert(len(i1), 2)
gtest.Assert(array1.Len(), 3)
t.AssertIN(i1, []interface{}{"a", "d", "c"})
t.Assert(len(i1), 2)
t.Assert(array1.Len(), 3)
i1 = array1.Rands(4)
gtest.Assert(len(i1), 3)
t.Assert(len(i1), 4)
})
}
func TestSortedArray_Join(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
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`)
t.Assert(array1.Join(","), `a,c,d`)
t.Assert(array1.Join("."), `a.c.d`)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, `"a"`, `\a`}
array1 := garray.NewSortedArrayFrom(a1, gutil.ComparatorString)
gtest.Assert(array1.Join("."), `"a".0.1.\a`)
t.Assert(array1.Join("."), `"a".0.1.\a`)
})
}
func TestSortedArray_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{0, 1, "a", "b"}
array1 := garray.NewSortedArrayFrom(a1, gutil.ComparatorString)
gtest.Assert(array1.String(), `[0,1,"a","b"]`)
t.Assert(array1.String(), `[0,1,"a","b"]`)
})
}
func TestSortedArray_CountValues(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "c"}
func1 := func(v1, v2 interface{}) int {
@ -453,15 +490,15 @@ func TestSortedArray_CountValues(t *testing.T) {
}
array1 := garray.NewSortedArrayFrom(a1, func1)
m1 := array1.CountValues()
gtest.Assert(len(m1), 3)
gtest.Assert(m1["c"], 2)
gtest.Assert(m1["a"], 1)
t.Assert(len(m1), 3)
t.Assert(m1["c"], 2)
t.Assert(m1["a"], 1)
})
}
func TestSortedArray_SetUnique(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []interface{}{"a", "d", "c", "c"}
func1 := func(v1, v2 interface{}) int {
@ -469,13 +506,13 @@ func TestSortedArray_SetUnique(t *testing.T) {
}
array1 := garray.NewSortedArrayFrom(a1, func1)
array1.SetUnique(true)
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1, []interface{}{"a", "c", "d"})
t.Assert(array1.Len(), 3)
t.Assert(array1, []interface{}{"a", "c", "d"})
})
}
func TestSortedArray_LockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
@ -504,13 +541,13 @@ func TestSortedArray_LockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
gtest.Assert(a1.Contains("g"), true)
t.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
t.Assert(a1.Contains("g"), true)
})
}
func TestSortedArray_RLockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
func1 := func(v1, v2 interface{}) int {
return strings.Compare(gconv.String(v1), gconv.String(v2))
}
@ -539,13 +576,13 @@ func TestSortedArray_RLockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候不会被阻塞。
gtest.Assert(a1.Contains("g"), true)
t.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候不会被阻塞。
t.Assert(a1.Contains("g"), true)
})
}
func TestSortedArray_Merge(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
func1 := func(v1, v2 interface{}) int {
if gconv.Int(v1) < gconv.Int(v2) {
return 0
@ -564,38 +601,38 @@ func TestSortedArray_Merge(t *testing.T) {
a1 := garray.NewSortedArrayFrom(s1, func1)
gtest.Assert(a1.Merge(s2).Len(), 6)
gtest.Assert(a1.Merge(i1).Len(), 9)
gtest.Assert(a1.Merge(i2).Len(), 10)
gtest.Assert(a1.Merge(s3).Len(), 12)
gtest.Assert(a1.Merge(s4).Len(), 14)
gtest.Assert(a1.Merge(s5).Len(), 16)
gtest.Assert(a1.Merge(s6).Len(), 19)
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 TestSortedArray_Json(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []interface{}{"a", "b", "d", "c"}
s2 := []interface{}{"a", "b", "c", "d"}
a1 := garray.NewSortedArrayFrom(s1, gutil.ComparatorString)
b1, err1 := json.Marshal(a1)
b2, err2 := json.Marshal(s1)
gtest.Assert(b1, b2)
gtest.Assert(err1, err2)
t.Assert(b1, b2)
t.Assert(err1, err2)
a2 := garray.NewSortedArray(gutil.ComparatorString)
err1 = json.Unmarshal(b2, &a2)
gtest.Assert(a2.Slice(), s2)
t.Assert(a2.Slice(), s2)
var a3 garray.SortedArray
err := json.Unmarshal(b2, &a3)
gtest.Assert(err, nil)
gtest.Assert(a3.Slice(), s1)
gtest.Assert(a3.Interfaces(), s1)
t.Assert(err, nil)
t.Assert(a3.Slice(), s1)
t.Assert(a3.Interfaces(), s1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
type User struct {
Name string
Scores *garray.SortedArray
@ -605,127 +642,140 @@ func TestSortedArray_Json(t *testing.T) {
"Scores": []int{99, 100, 98},
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
user := new(User)
err = json.Unmarshal(b, user)
gtest.Assert(err, nil)
gtest.Assert(user.Name, data["Name"])
gtest.AssertNE(user.Scores, nil)
gtest.Assert(user.Scores.Len(), 3)
gtest.AssertIN(user.Scores.PopLeft(), data["Scores"])
gtest.AssertIN(user.Scores.PopLeft(), data["Scores"])
gtest.AssertIN(user.Scores.PopLeft(), data["Scores"])
t.Assert(err, nil)
t.Assert(user.Name, data["Name"])
t.AssertNE(user.Scores, nil)
t.Assert(user.Scores.Len(), 3)
v, ok := user.Scores.PopLeft()
t.AssertIN(v, data["Scores"])
t.Assert(ok, true)
v, ok = user.Scores.PopLeft()
t.AssertIN(v, data["Scores"])
t.Assert(ok, true)
v, ok = user.Scores.PopLeft()
t.AssertIN(v, data["Scores"])
t.Assert(ok, true)
v, ok = user.Scores.PopLeft()
t.Assert(v, nil)
t.Assert(ok, false)
})
}
func TestSortedArray_Iterator(t *testing.T) {
slice := g.Slice{"a", "b", "d", "c"}
array := garray.NewSortedArrayFrom(slice, gutil.ComparatorString)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.Iterator(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorAsc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorDesc(func(k int, v interface{}) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.Iterator(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorAsc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorDesc(func(k int, v interface{}) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
}
func TestSortedArray_RemoveValue(t *testing.T) {
slice := g.Slice{"a", "b", "d", "c"}
array := garray.NewSortedArrayFrom(slice, gutil.ComparatorString)
gtest.Case(t, func() {
gtest.Assert(array.RemoveValue("e"), false)
gtest.Assert(array.RemoveValue("b"), true)
gtest.Assert(array.RemoveValue("a"), true)
gtest.Assert(array.RemoveValue("c"), true)
gtest.Assert(array.RemoveValue("f"), false)
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 TestSortedArray_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Array *garray.SortedArray
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`[2,3,1]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": g.Slice{2, 3, 1},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
})
}
func TestSortedArray_FilterNil(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
values := g.Slice{0, 1, 2, 3, 4, "", g.Slice{}}
array := garray.NewSortedArrayFromCopy(values, gutil.ComparatorInt)
gtest.Assert(array.FilterNil().Slice(), g.Slice{0, "", g.Slice{}, 1, 2, 3, 4})
t.Assert(array.FilterNil().Slice(), g.Slice{0, "", g.Slice{}, 1, 2, 3, 4})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedArrayFromCopy(g.Slice{nil, 1, 2, 3, 4, nil}, gutil.ComparatorInt)
gtest.Assert(array.FilterNil(), g.Slice{1, 2, 3, 4})
t.Assert(array.FilterNil(), g.Slice{1, 2, 3, 4})
})
}
func TestSortedArray_FilterEmpty(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedArrayFrom(g.Slice{0, 1, 2, 3, 4, "", g.Slice{}}, gutil.ComparatorInt)
gtest.Assert(array.FilterEmpty(), g.Slice{1, 2, 3, 4})
t.Assert(array.FilterEmpty(), g.Slice{1, 2, 3, 4})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedArrayFrom(g.Slice{1, 2, 3, 4}, gutil.ComparatorInt)
gtest.Assert(array.FilterEmpty(), g.Slice{1, 2, 3, 4})
t.Assert(array.FilterEmpty(), g.Slice{1, 2, 3, 4})
})
}

View File

@ -21,355 +21,399 @@ import (
)
func TestNewSortedIntArrayFrom(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{0, 3, 2, 1, 4, 5, 6}
array1 := garray.NewSortedIntArrayFrom(a1, true)
gtest.Assert(array1.Join("."), "0.1.2.3.4.5.6")
gtest.Assert(array1.Slice(), a1)
gtest.Assert(array1.Interfaces(), a1)
t.Assert(array1.Join("."), "0.1.2.3.4.5.6")
t.Assert(array1.Slice(), a1)
t.Assert(array1.Interfaces(), a1)
})
}
func TestNewSortedIntArrayFromCopy(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{0, 5, 2, 1, 4, 3, 6}
array1 := garray.NewSortedIntArrayFromCopy(a1, false)
gtest.Assert(array1.Join("."), "0.1.2.3.4.5.6")
t.Assert(array1.Join("."), "0.1.2.3.4.5.6")
})
}
func TestSortedIntArray_SetArray(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{0, 1, 2, 3}
a2 := []int{4, 5, 6}
array1 := garray.NewSortedIntArrayFrom(a1)
array2 := array1.SetArray(a2)
gtest.Assert(array2.Len(), 3)
gtest.Assert(array2.Search(3), -1)
gtest.Assert(array2.Search(5), 1)
gtest.Assert(array2.Search(6), 2)
t.Assert(array2.Len(), 3)
t.Assert(array2.Search(3), -1)
t.Assert(array2.Search(5), 1)
t.Assert(array2.Search(6), 2)
})
}
func TestSortedIntArray_Sort(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
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})
t.Assert(array2.Len(), 4)
t.Assert(array2, []int{0, 1, 2, 3})
})
}
func TestSortedIntArray_Get(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 0}
array1 := garray.NewSortedIntArrayFrom(a1)
gtest.Assert(array1.Get(0), 0)
gtest.Assert(array1.Get(1), 1)
gtest.Assert(array1.Get(3), 5)
v, ok := array1.Get(0)
t.Assert(v, 0)
t.Assert(ok, true)
v, ok = array1.Get(1)
t.Assert(v, 1)
t.Assert(ok, true)
v, ok = array1.Get(3)
t.Assert(v, 5)
t.Assert(ok, true)
})
}
func TestSortedIntArray_Remove(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 0}
array1 := garray.NewSortedIntArrayFrom(a1)
gtest.Assert(array1.Remove(-1), 0)
gtest.Assert(array1.Remove(100000), 0)
v, ok := array1.Remove(-1)
t.Assert(v, 0)
t.Assert(ok, false)
i1 := array1.Remove(2)
gtest.Assert(i1, 3)
gtest.Assert(array1.Search(5), 2)
v, ok = array1.Remove(-100000)
t.Assert(v, 0)
t.Assert(ok, false)
// 再次删除剩下的数组中的第一个
i2 := array1.Remove(0)
gtest.Assert(i2, 0)
gtest.Assert(array1.Search(5), 1)
v, ok = array1.Remove(2)
t.Assert(v, 3)
t.Assert(ok, true)
t.Assert(array1.Search(5), 2)
v, ok = array1.Remove(0)
t.Assert(v, 0)
t.Assert(ok, true)
t.Assert(array1.Search(5), 1)
a2 := []int{1, 3, 4}
array2 := garray.NewSortedIntArrayFrom(a2)
i3 := array2.Remove(1)
gtest.Assert(array2.Search(1), 0)
gtest.Assert(i3, 3)
i3 = array2.Remove(1)
gtest.Assert(array2.Search(4), -1)
gtest.Assert(i3, 4)
v, ok = array2.Remove(1)
t.Assert(v, 3)
t.Assert(ok, true)
t.Assert(array2.Search(1), 0)
v, ok = array2.Remove(1)
t.Assert(v, 4)
t.Assert(ok, true)
t.Assert(array2.Search(4), -1)
})
}
func TestSortedIntArray_PopLeft(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 2}
array1 := garray.NewSortedIntArrayFrom(a1)
i1 := array1.PopLeft()
gtest.Assert(i1, 1)
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1.Search(1), -1)
v, ok := array1.PopLeft()
t.Assert(v, 1)
t.Assert(ok, true)
t.Assert(array1.Len(), 3)
t.Assert(array1.Search(1), -1)
})
}
func TestSortedIntArray_PopRight(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 2}
array1 := garray.NewSortedIntArrayFrom(a1)
i1 := array1.PopRight()
gtest.Assert(i1, 5)
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1.Search(5), -1)
v, ok := array1.PopRight()
t.Assert(v, 5)
t.Assert(ok, true)
t.Assert(array1.Len(), 3)
t.Assert(array1.Search(5), -1)
})
}
func TestSortedIntArray_PopRand(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 2}
array1 := garray.NewSortedIntArrayFrom(a1)
i1 := array1.PopRand()
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1.Search(i1), -1)
gtest.AssertIN(i1, []int{1, 3, 5, 2})
i1, ok := array1.PopRand()
t.Assert(ok, true)
t.Assert(array1.Len(), 3)
t.Assert(array1.Search(i1), -1)
t.AssertIN(i1, []int{1, 3, 5, 2})
})
}
func TestSortedIntArray_PopRands(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 2}
array1 := garray.NewSortedIntArrayFrom(a1)
ns1 := array1.PopRands(2)
gtest.Assert(array1.Len(), 2)
gtest.AssertIN(ns1, []int{1, 3, 5, 2})
t.Assert(array1.Len(), 2)
t.AssertIN(ns1, []int{1, 3, 5, 2})
a2 := []int{1, 3, 5, 2}
array2 := garray.NewSortedIntArrayFrom(a2)
ns2 := array2.PopRands(5)
gtest.Assert(array2.Len(), 0)
gtest.Assert(len(ns2), 4)
gtest.AssertIN(ns2, []int{1, 3, 5, 2})
t.Assert(array2.Len(), 0)
t.Assert(len(ns2), 4)
t.AssertIN(ns2, []int{1, 3, 5, 2})
})
}
func TestSortedIntArray_Empty(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedIntArray()
v, ok := array.PopLeft()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopLefts(10), nil)
v, ok = array.PopRight()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopRights(10), nil)
v, ok = array.PopRand()
t.Assert(v, 0)
t.Assert(ok, false)
t.Assert(array.PopRands(10), nil)
})
}
func TestSortedIntArray_PopLefts(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 2}
array1 := garray.NewSortedIntArrayFrom(a1)
ns1 := array1.PopLefts(2)
gtest.Assert(array1.Len(), 2)
gtest.Assert(ns1, []int{1, 2})
t.Assert(array1.Len(), 2)
t.Assert(ns1, []int{1, 2})
a2 := []int{1, 3, 5, 2}
array2 := garray.NewSortedIntArrayFrom(a2)
ns2 := array2.PopLefts(5)
gtest.Assert(array2.Len(), 0)
gtest.AssertIN(ns2, []int{1, 3, 5, 2})
t.Assert(array2.Len(), 0)
t.AssertIN(ns2, []int{1, 3, 5, 2})
})
}
func TestSortedIntArray_PopRights(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5, 2}
array1 := garray.NewSortedIntArrayFrom(a1)
ns1 := array1.PopRights(2)
gtest.Assert(array1.Len(), 2)
gtest.Assert(ns1, []int{3, 5})
t.Assert(array1.Len(), 2)
t.Assert(ns1, []int{3, 5})
a2 := []int{1, 3, 5, 2}
array2 := garray.NewSortedIntArrayFrom(a2)
ns2 := array2.PopRights(5)
gtest.Assert(array2.Len(), 0)
gtest.AssertIN(ns2, []int{1, 3, 5, 2})
t.Assert(array2.Len(), 0)
t.AssertIN(ns2, []int{1, 3, 5, 2})
})
}
func TestSortedIntArray_Range(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
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})
t.Assert(len(ns1), 3)
t.Assert(ns1, []int{2, 3, 5})
ns2 := array1.Range(5, 4)
gtest.Assert(len(ns2), 0)
t.Assert(len(ns2), 0)
ns3 := array1.Range(-1, 4)
gtest.Assert(len(ns3), 4)
t.Assert(len(ns3), 4)
nsl := array1.Range(5, 8)
gtest.Assert(len(nsl), 1)
gtest.Assert(array2.Range(1, 2), []int{2})
t.Assert(len(nsl), 1)
t.Assert(array2.Range(1, 2), []int{2})
})
}
func TestSortedIntArray_Sum(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
n1 := array1.Sum()
gtest.Assert(n1, 9)
t.Assert(n1, 9)
})
}
func TestSortedIntArray_Join(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
gtest.Assert(array1.Join("."), `1.3.5`)
t.Assert(array1.Join("."), `1.3.5`)
})
}
func TestSortedIntArray_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
gtest.Assert(array1.String(), `[1,3,5]`)
t.Assert(array1.String(), `[1,3,5]`)
})
}
func TestSortedIntArray_Contains(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
gtest.Assert(array1.Contains(4), false)
t.Assert(array1.Contains(4), false)
})
}
func TestSortedIntArray_Clone(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
array2 := array1.Clone()
gtest.Assert(array2.Len(), 3)
gtest.Assert(array2, array1)
t.Assert(array2.Len(), 3)
t.Assert(array2, array1)
})
}
func TestSortedIntArray_Clear(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 3, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
array1.Clear()
gtest.Assert(array1.Len(), 0)
t.Assert(array1.Len(), 0)
})
}
func TestSortedIntArray_Chunk(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
ns1 := array1.Chunk(2) //按每几个元素切成一个数组
ns2 := array1.Chunk(-1)
gtest.Assert(len(ns1), 3)
gtest.Assert(ns1[0], []int{1, 2})
gtest.Assert(ns1[2], []int{5})
gtest.Assert(len(ns2), 0)
t.Assert(len(ns1), 3)
t.Assert(ns1[0], []int{1, 2})
t.Assert(ns1[2], []int{5})
t.Assert(len(ns2), 0)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []int{1, 2, 3})
gtest.Assert(chunks[1], []int{4, 5})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 2)
t.Assert(chunks[0], []int{1, 2, 3})
t.Assert(chunks[1], []int{4, 5})
t.Assert(array1.Chunk(0), nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5, 6}
array1 := garray.NewSortedIntArrayFrom(a1)
chunks := array1.Chunk(2)
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, 6})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 3)
t.Assert(chunks[0], []int{1, 2})
t.Assert(chunks[1], []int{3, 4})
t.Assert(chunks[2], []int{5, 6})
t.Assert(array1.Chunk(0), nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5, 6}
array1 := garray.NewSortedIntArrayFrom(a1)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []int{1, 2, 3})
gtest.Assert(chunks[1], []int{4, 5, 6})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(chunks), 2)
t.Assert(chunks[0], []int{1, 2, 3})
t.Assert(chunks[1], []int{4, 5, 6})
t.Assert(array1.Chunk(0), nil)
})
}
func TestSortedIntArray_SubSlice(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
array2 := garray.NewSortedIntArrayFrom(a1, true)
ns1 := array1.SubSlice(1, 2)
gtest.Assert(len(ns1), 2)
gtest.Assert(ns1, []int{2, 3})
t.Assert(len(ns1), 2)
t.Assert(ns1, []int{2, 3})
ns2 := array1.SubSlice(7, 2)
gtest.Assert(len(ns2), 0)
t.Assert(len(ns2), 0)
ns3 := array1.SubSlice(3, 5)
gtest.Assert(len(ns3), 2)
gtest.Assert(ns3, []int{4, 5})
t.Assert(len(ns3), 2)
t.Assert(ns3, []int{4, 5})
ns4 := array1.SubSlice(3, 1)
gtest.Assert(len(ns4), 1)
gtest.Assert(ns4, []int{4})
gtest.Assert(array1.SubSlice(-1, 1), []int{5})
gtest.Assert(array1.SubSlice(-9, 1), nil)
gtest.Assert(array1.SubSlice(1, -9), nil)
gtest.Assert(array2.SubSlice(1, 2), []int{2, 3})
t.Assert(len(ns4), 1)
t.Assert(ns4, []int{4})
t.Assert(array1.SubSlice(-1, 1), []int{5})
t.Assert(array1.SubSlice(-9, 1), nil)
t.Assert(array1.SubSlice(1, -9), nil)
t.Assert(array2.SubSlice(1, 2), []int{2, 3})
})
}
func TestSortedIntArray_Rand(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
ns1 := array1.Rand() //按每几个元素切成一个数组
gtest.AssertIN(ns1, a1)
ns1, ok := array1.Rand()
t.AssertIN(ns1, a1)
t.Assert(ok, true)
})
}
func TestSortedIntArray_Rands(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5}
array1 := garray.NewSortedIntArrayFrom(a1)
ns1 := array1.Rands(2) //按每几个元素切成一个数组
gtest.AssertIN(ns1, a1)
gtest.Assert(len(ns1), 2)
ns1 := array1.Rands(2)
t.AssertIN(ns1, a1)
t.Assert(len(ns1), 2)
ns2 := array1.Rands(6) //按每几个元素切成一个数组
gtest.AssertIN(ns2, a1)
gtest.Assert(len(ns2), 5)
ns2 := array1.Rands(6)
t.Assert(len(ns2), 6)
})
}
func TestSortedIntArray_CountValues(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5, 3}
array1 := garray.NewSortedIntArrayFrom(a1)
ns1 := array1.CountValues() //按每几个元素切成一个数组
gtest.Assert(len(ns1), 5)
gtest.Assert(ns1[2], 1)
gtest.Assert(ns1[3], 2)
t.Assert(len(ns1), 5)
t.Assert(ns1[2], 1)
t.Assert(ns1[3], 2)
})
}
func TestSortedIntArray_SetUnique(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []int{1, 2, 3, 4, 5, 3}
array1 := garray.NewSortedIntArrayFrom(a1)
array1.SetUnique(true)
gtest.Assert(array1.Len(), 5)
gtest.Assert(array1, []int{1, 2, 3, 4, 5})
t.Assert(array1.Len(), 5)
t.Assert(array1, []int{1, 2, 3, 4, 5})
})
}
func TestSortedIntArray_LockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []int{1, 2, 3, 4}
a1 := garray.NewSortedIntArrayFrom(s1, true)
ch1 := make(chan int64, 3)
@ -394,13 +438,13 @@ func TestSortedIntArray_LockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
gtest.Assert(a1.Contains(6), true)
t.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
t.Assert(a1.Contains(6), true)
})
}
func TestSortedIntArray_RLockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []int{1, 2, 3, 4}
a1 := garray.NewSortedIntArrayFrom(s1, true)
@ -426,13 +470,13 @@ func TestSortedIntArray_RLockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候并没有阻塞。
gtest.Assert(a1.Contains(6), true)
t.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候并没有阻塞。
t.Assert(a1.Contains(6), true)
})
}
func TestSortedIntArray_Merge(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
func1 := func(v1, v2 interface{}) int {
if gconv.Int(v1) < gconv.Int(v2) {
return 0
@ -449,37 +493,37 @@ func TestSortedIntArray_Merge(t *testing.T) {
s6 := garray.NewSortedIntArrayFrom([]int{1, 2, 3})
a1 := garray.NewSortedIntArrayFrom(i0)
gtest.Assert(a1.Merge(s2).Len(), 6)
gtest.Assert(a1.Merge(i1).Len(), 9)
gtest.Assert(a1.Merge(i2).Len(), 10)
gtest.Assert(a1.Merge(s3).Len(), 12)
gtest.Assert(a1.Merge(s4).Len(), 14)
gtest.Assert(a1.Merge(s5).Len(), 16)
gtest.Assert(a1.Merge(s6).Len(), 19)
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 TestSortedIntArray_Json(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []int{1, 4, 3, 2}
s2 := []int{1, 2, 3, 4}
a1 := garray.NewSortedIntArrayFrom(s1)
b1, err1 := json.Marshal(a1)
b2, err2 := json.Marshal(s1)
gtest.Assert(b1, b2)
gtest.Assert(err1, err2)
t.Assert(b1, b2)
t.Assert(err1, err2)
a2 := garray.NewSortedIntArray()
err1 = json.Unmarshal(b2, &a2)
gtest.Assert(a2.Slice(), s2)
t.Assert(a2.Slice(), s2)
var a3 garray.SortedIntArray
err := json.Unmarshal(b2, &a3)
gtest.Assert(err, nil)
gtest.Assert(a3.Slice(), s1)
t.Assert(err, nil)
t.Assert(a3.Slice(), s1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
type User struct {
Name string
Scores *garray.SortedIntArray
@ -489,112 +533,112 @@ func TestSortedIntArray_Json(t *testing.T) {
"Scores": []int{99, 100, 98},
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
user := new(User)
err = json.Unmarshal(b, user)
gtest.Assert(err, nil)
gtest.Assert(user.Name, data["Name"])
gtest.Assert(user.Scores, []int{98, 99, 100})
t.Assert(err, nil)
t.Assert(user.Name, data["Name"])
t.Assert(user.Scores, []int{98, 99, 100})
})
}
func TestSortedIntArray_Iterator(t *testing.T) {
slice := g.SliceInt{10, 20, 30, 40}
array := garray.NewSortedIntArrayFrom(slice)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.Iterator(func(k int, v int) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorAsc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorDesc(func(k int, v int) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.Iterator(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorAsc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorDesc(func(k int, v int) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
}
func TestSortedIntArray_RemoveValue(t *testing.T) {
slice := g.SliceInt{10, 20, 30, 40}
array := garray.NewSortedIntArrayFrom(slice)
gtest.Case(t, func() {
gtest.Assert(array.RemoveValue(99), false)
gtest.Assert(array.RemoveValue(20), true)
gtest.Assert(array.RemoveValue(10), true)
gtest.Assert(array.RemoveValue(20), false)
gtest.Assert(array.RemoveValue(88), false)
gtest.Assert(array.Len(), 2)
gtest.C(t, func(t *gtest.T) {
t.Assert(array.RemoveValue(99), false)
t.Assert(array.RemoveValue(20), true)
t.Assert(array.RemoveValue(10), true)
t.Assert(array.RemoveValue(20), false)
t.Assert(array.RemoveValue(88), false)
t.Assert(array.Len(), 2)
})
}
func TestSortedIntArray_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Array *garray.SortedIntArray
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`[2,3,1]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": g.Slice{2, 3, 1},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
})
}
func TestSortedIntArray_FilterEmpty(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedIntArrayFrom(g.SliceInt{0, 1, 2, 3, 4, 0})
gtest.Assert(array.FilterEmpty(), g.SliceInt{1, 2, 3, 4})
t.Assert(array.FilterEmpty(), g.SliceInt{1, 2, 3, 4})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedIntArrayFrom(g.SliceInt{1, 2, 3, 4})
gtest.Assert(array.FilterEmpty(), g.SliceInt{1, 2, 3, 4})
t.Assert(array.FilterEmpty(), g.SliceInt{1, 2, 3, 4})
})
}

View File

@ -20,362 +20,407 @@ import (
)
func TestNewSortedStrArrayFrom(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"a", "d", "c", "b"}
s1 := garray.NewSortedStrArrayFrom(a1, true)
gtest.Assert(s1, []string{"a", "b", "c", "d"})
t.Assert(s1, []string{"a", "b", "c", "d"})
s2 := garray.NewSortedStrArrayFrom(a1, false)
gtest.Assert(s2, []string{"a", "b", "c", "d"})
t.Assert(s2, []string{"a", "b", "c", "d"})
})
}
func TestNewSortedStrArrayFromCopy(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"a", "d", "c", "b"}
s1 := garray.NewSortedStrArrayFromCopy(a1, true)
gtest.Assert(s1.Len(), 4)
gtest.Assert(s1, []string{"a", "b", "c", "d"})
t.Assert(s1.Len(), 4)
t.Assert(s1, []string{"a", "b", "c", "d"})
})
}
func TestSortedStrArray_SetArray(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"a", "d", "c", "b"}
a2 := []string{"f", "g", "h"}
array1 := garray.NewSortedStrArrayFrom(a1)
array1.SetArray(a2)
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1.Contains("d"), false)
gtest.Assert(array1.Contains("b"), false)
gtest.Assert(array1.Contains("g"), true)
t.Assert(array1.Len(), 3)
t.Assert(array1.Contains("d"), false)
t.Assert(array1.Contains("b"), false)
t.Assert(array1.Contains("g"), true)
})
}
func TestSortedStrArray_Sort(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
gtest.Assert(array1, []string{"a", "b", "c", "d"})
t.Assert(array1, []string{"a", "b", "c", "d"})
array1.Sort()
gtest.Assert(array1.Len(), 4)
gtest.Assert(array1.Contains("c"), true)
gtest.Assert(array1, []string{"a", "b", "c", "d"})
t.Assert(array1.Len(), 4)
t.Assert(array1.Contains("c"), true)
t.Assert(array1, []string{"a", "b", "c", "d"})
})
}
func TestSortedStrArray_Get(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
gtest.Assert(array1.Get(2), "c")
gtest.Assert(array1.Get(0), "a")
v, ok := array1.Get(2)
t.Assert(v, "c")
t.Assert(ok, true)
v, ok = array1.Get(0)
t.Assert(v, "a")
t.Assert(ok, true)
})
}
func TestSortedStrArray_Remove(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
gtest.Assert(array1.Remove(-1), "")
gtest.Assert(array1.Remove(100000), "")
v, ok := array1.Remove(-1)
t.Assert(v, "")
t.Assert(ok, false)
gtest.Assert(array1.Remove(2), "c")
gtest.Assert(array1.Get(2), "d")
gtest.Assert(array1.Len(), 3)
gtest.Assert(array1.Contains("c"), false)
v, ok = array1.Remove(100000)
t.Assert(v, "")
t.Assert(ok, false)
gtest.Assert(array1.Remove(0), "a")
gtest.Assert(array1.Len(), 2)
gtest.Assert(array1.Contains("a"), false)
v, ok = array1.Remove(2)
t.Assert(v, "c")
t.Assert(ok, true)
// 此时array1里的元素只剩下2个
gtest.Assert(array1.Remove(1), "d")
gtest.Assert(array1.Len(), 1)
v, ok = array1.Get(2)
t.Assert(v, "d")
t.Assert(ok, true)
t.Assert(array1.Len(), 3)
t.Assert(array1.Contains("c"), false)
v, ok = array1.Remove(0)
t.Assert(v, "a")
t.Assert(ok, true)
t.Assert(array1.Len(), 2)
t.Assert(array1.Contains("a"), false)
v, ok = array1.Remove(1)
t.Assert(v, "d")
t.Assert(ok, true)
t.Assert(array1.Len(), 1)
})
}
func TestSortedStrArray_PopLeft(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
s1 := array1.PopLeft()
gtest.Assert(s1, "a")
gtest.Assert(array1.Len(), 4)
gtest.Assert(array1.Contains("a"), false)
v, ok := array1.PopLeft()
t.Assert(v, "a")
t.Assert(ok, true)
t.Assert(array1.Len(), 4)
t.Assert(array1.Contains("a"), false)
})
}
func TestSortedStrArray_PopRight(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
s1 := array1.PopRight()
gtest.Assert(s1, "e")
gtest.Assert(array1.Len(), 4)
gtest.Assert(array1.Contains("e"), false)
v, ok := array1.PopRight()
t.Assert(v, "e")
t.Assert(ok, ok)
t.Assert(array1.Len(), 4)
t.Assert(array1.Contains("e"), false)
})
}
func TestSortedStrArray_PopRand(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
s1 := array1.PopRand()
gtest.AssertIN(s1, []string{"e", "a", "d", "c", "b"})
gtest.Assert(array1.Len(), 4)
gtest.Assert(array1.Contains(s1), false)
s1, ok := array1.PopRand()
t.Assert(ok, true)
t.AssertIN(s1, []string{"e", "a", "d", "c", "b"})
t.Assert(array1.Len(), 4)
t.Assert(array1.Contains(s1), false)
})
}
func TestSortedStrArray_PopRands(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
s1 := array1.PopRands(2)
gtest.AssertIN(s1, []string{"e", "a", "d", "c", "b"})
gtest.Assert(array1.Len(), 3)
gtest.Assert(len(s1), 2)
t.AssertIN(s1, []string{"e", "a", "d", "c", "b"})
t.Assert(array1.Len(), 3)
t.Assert(len(s1), 2)
s1 = array1.PopRands(4)
gtest.Assert(len(s1), 3)
gtest.AssertIN(s1, []string{"e", "a", "d", "c", "b"})
t.Assert(len(s1), 3)
t.AssertIN(s1, []string{"e", "a", "d", "c", "b"})
})
}
func TestSortedStrArray_Empty(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedStrArray()
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)
})
}
func TestSortedStrArray_PopLefts(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b"}
array1 := garray.NewSortedStrArrayFrom(a1)
s1 := array1.PopLefts(2)
gtest.Assert(s1, []string{"a", "b"})
gtest.Assert(array1.Len(), 3)
gtest.Assert(len(s1), 2)
t.Assert(s1, []string{"a", "b"})
t.Assert(array1.Len(), 3)
t.Assert(len(s1), 2)
s1 = array1.PopLefts(4)
gtest.Assert(len(s1), 3)
gtest.Assert(s1, []string{"c", "d", "e"})
t.Assert(len(s1), 3)
t.Assert(s1, []string{"c", "d", "e"})
})
}
func TestSortedStrArray_PopRights(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b", "f", "g"}
array1 := garray.NewSortedStrArrayFrom(a1)
s1 := array1.PopRights(2)
gtest.Assert(s1, []string{"f", "g"})
gtest.Assert(array1.Len(), 5)
gtest.Assert(len(s1), 2)
t.Assert(s1, []string{"f", "g"})
t.Assert(array1.Len(), 5)
t.Assert(len(s1), 2)
s1 = array1.PopRights(6)
gtest.Assert(len(s1), 5)
gtest.Assert(s1, []string{"a", "b", "c", "d", "e"})
gtest.Assert(array1.Len(), 0)
t.Assert(len(s1), 5)
t.Assert(s1, []string{"a", "b", "c", "d", "e"})
t.Assert(array1.Len(), 0)
})
}
func TestSortedStrArray_Range(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b", "f", "g"}
array1 := garray.NewSortedStrArrayFrom(a1)
array2 := garray.NewSortedStrArrayFrom(a1, true)
s1 := array1.Range(2, 4)
gtest.Assert(len(s1), 2)
gtest.Assert(s1, []string{"c", "d"})
t.Assert(len(s1), 2)
t.Assert(s1, []string{"c", "d"})
s1 = array1.Range(-1, 2)
gtest.Assert(len(s1), 2)
gtest.Assert(s1, []string{"a", "b"})
t.Assert(len(s1), 2)
t.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(10, 2), nil)
t.Assert(len(s1), 3)
t.Assert(s1, []string{"e", "f", "g"})
t.Assert(array1.Range(10, 2), nil)
s2 := array2.Range(2, 4)
gtest.Assert(s2, []string{"c", "d"})
t.Assert(s2, []string{"c", "d"})
})
}
func TestSortedStrArray_Sum(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b", "f", "g"}
a2 := []string{"1", "2", "3", "4", "a"}
array1 := garray.NewSortedStrArrayFrom(a1)
array2 := garray.NewSortedStrArrayFrom(a2)
gtest.Assert(array1.Sum(), 0)
gtest.Assert(array2.Sum(), 10)
t.Assert(array1.Sum(), 0)
t.Assert(array2.Sum(), 10)
})
}
func TestSortedStrArray_Clone(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b", "f", "g"}
array1 := garray.NewSortedStrArrayFrom(a1)
array2 := array1.Clone()
gtest.Assert(array1, array2)
t.Assert(array1, array2)
array1.Remove(1)
gtest.Assert(array2.Len(), 7)
t.Assert(array2.Len(), 7)
})
}
func TestSortedStrArray_Clear(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b", "f", "g"}
array1 := garray.NewSortedStrArrayFrom(a1)
array1.Clear()
gtest.Assert(array1.Len(), 0)
t.Assert(array1.Len(), 0)
})
}
func TestSortedStrArray_SubSlice(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b", "f", "g"}
array1 := garray.NewSortedStrArrayFrom(a1)
array2 := garray.NewSortedStrArrayFrom(a1, true)
s1 := array1.SubSlice(1, 3)
gtest.Assert(len(s1), 3)
gtest.Assert(s1, []string{"b", "c", "d"})
gtest.Assert(array1.Len(), 7)
t.Assert(len(s1), 3)
t.Assert(s1, []string{"b", "c", "d"})
t.Assert(array1.Len(), 7)
s2 := array1.SubSlice(1, 10)
gtest.Assert(len(s2), 6)
t.Assert(len(s2), 6)
s3 := array1.SubSlice(10, 2)
gtest.Assert(len(s3), 0)
t.Assert(len(s3), 0)
s3 = array1.SubSlice(-5, 2)
gtest.Assert(s3, []string{"c", "d"})
t.Assert(s3, []string{"c", "d"})
s3 = array1.SubSlice(-10, 2)
gtest.Assert(s3, nil)
t.Assert(s3, nil)
s3 = array1.SubSlice(1, -2)
gtest.Assert(s3, nil)
t.Assert(s3, nil)
gtest.Assert(array2.SubSlice(1, 3), []string{"b", "c", "d"})
t.Assert(array2.SubSlice(1, 3), []string{"b", "c", "d"})
})
}
func TestSortedStrArray_Len(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "c", "b", "f", "g"}
array1 := garray.NewSortedStrArrayFrom(a1)
gtest.Assert(array1.Len(), 7)
t.Assert(array1.Len(), 7)
})
}
func TestSortedStrArray_Rand(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d"}
array1 := garray.NewSortedStrArrayFrom(a1)
gtest.AssertIN(array1.Rand(), []string{"e", "a", "d"})
v, ok := array1.Rand()
t.AssertIN(v, []string{"e", "a", "d"})
t.Assert(ok, true)
})
}
func TestSortedStrArray_Rands(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d"}
array1 := garray.NewSortedStrArrayFrom(a1)
s1 := array1.Rands(2)
gtest.AssertIN(s1, []string{"e", "a", "d"})
gtest.Assert(len(s1), 2)
t.AssertIN(s1, []string{"e", "a", "d"})
t.Assert(len(s1), 2)
s1 = array1.Rands(4)
gtest.AssertIN(s1, []string{"e", "a", "d"})
gtest.Assert(len(s1), 3)
t.Assert(len(s1), 4)
})
}
func TestSortedStrArray_Join(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d"}
array1 := garray.NewSortedStrArrayFrom(a1)
gtest.Assert(array1.Join(","), `a,d,e`)
gtest.Assert(array1.Join("."), `a.d.e`)
t.Assert(array1.Join(","), `a,d,e`)
t.Assert(array1.Join("."), `a.d.e`)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"a", `"b"`, `\c`}
array1 := garray.NewSortedStrArrayFrom(a1)
gtest.Assert(array1.Join("."), `"b".\c.a`)
t.Assert(array1.Join("."), `"b".\c.a`)
})
}
func TestSortedStrArray_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d"}
array1 := garray.NewSortedStrArrayFrom(a1)
gtest.Assert(array1.String(), `["a","d","e"]`)
t.Assert(array1.String(), `["a","d","e"]`)
})
}
func TestSortedStrArray_CountValues(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "a", "c"}
array1 := garray.NewSortedStrArrayFrom(a1)
m1 := array1.CountValues()
gtest.Assert(m1["a"], 2)
gtest.Assert(m1["d"], 1)
t.Assert(m1["a"], 2)
t.Assert(m1["d"], 1)
})
}
func TestSortedStrArray_Chunk(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "a", "c"}
array1 := garray.NewSortedStrArrayFrom(a1)
array2 := array1.Chunk(2)
gtest.Assert(len(array2), 3)
gtest.Assert(len(array2[0]), 2)
gtest.Assert(array2[1], []string{"c", "d"})
gtest.Assert(array1.Chunk(0), nil)
t.Assert(len(array2), 3)
t.Assert(len(array2[0]), 2)
t.Assert(array2[1], []string{"c", "d"})
t.Assert(array1.Chunk(0), nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"1", "2", "3", "4", "5"}
array1 := garray.NewSortedStrArrayFrom(a1)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []string{"1", "2", "3"})
gtest.Assert(chunks[1], []string{"4", "5"})
gtest.Assert(array1.Chunk(0), nil)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"1", "2", "3", "4", "5", "6"}
array1 := garray.NewSortedStrArrayFrom(a1)
chunks := array1.Chunk(2)
gtest.Assert(len(chunks), 3)
gtest.Assert(chunks[0], []string{"1", "2"})
gtest.Assert(chunks[1], []string{"3", "4"})
gtest.Assert(chunks[2], []string{"5", "6"})
gtest.Assert(array1.Chunk(0), nil)
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.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"1", "2", "3", "4", "5", "6"}
array1 := garray.NewSortedStrArrayFrom(a1)
chunks := array1.Chunk(3)
gtest.Assert(len(chunks), 2)
gtest.Assert(chunks[0], []string{"1", "2", "3"})
gtest.Assert(chunks[1], []string{"4", "5", "6"})
gtest.Assert(array1.Chunk(0), nil)
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 TestSortedStrArray_SetUnique(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a1 := []string{"e", "a", "d", "a", "c"}
array1 := garray.NewSortedStrArrayFrom(a1)
array2 := array1.SetUnique(true)
gtest.Assert(array2.Len(), 4)
gtest.Assert(array2, []string{"a", "c", "d", "e"})
t.Assert(array2.Len(), 4)
t.Assert(array2, []string{"a", "c", "d", "e"})
})
}
func TestSortedStrArray_LockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []string{"a", "b", "c", "d"}
a1 := garray.NewSortedStrArrayFrom(s1, true)
@ -401,13 +446,13 @@ func TestSortedStrArray_LockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
gtest.Assert(a1.Contains("g"), true)
t.AssertGT(t2-t1, 20) //go1加的读写互斥锁所go2读的时候被阻塞。
t.Assert(a1.Contains("g"), true)
})
}
func TestSortedStrArray_RLockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []string{"a", "b", "c", "d"}
a1 := garray.NewSortedStrArrayFrom(s1, true)
@ -433,13 +478,13 @@ func TestSortedStrArray_RLockFunc(t *testing.T) {
<-ch2 //等待go1完成
// 防止ci抖动,以豪秒为单位
gtest.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候并没有阻塞。
gtest.Assert(a1.Contains("g"), true)
t.AssertLT(t2-t1, 20) //go1加的读锁所go2读的时候并没有阻塞。
t.Assert(a1.Contains("g"), true)
})
}
func TestSortedStrArray_Merge(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
func1 := func(v1, v2 interface{}) int {
if gconv.Int(v1) < gconv.Int(v2) {
return 0
@ -457,39 +502,39 @@ func TestSortedStrArray_Merge(t *testing.T) {
s6 := garray.NewSortedIntArrayFrom([]int{1, 2, 3})
a1 := garray.NewSortedStrArrayFrom(s1)
gtest.Assert(a1.Merge(s2).Len(), 6)
gtest.Assert(a1.Merge(i1).Len(), 9)
gtest.Assert(a1.Merge(i2).Len(), 10)
gtest.Assert(a1.Merge(s3).Len(), 12)
gtest.Assert(a1.Merge(s4).Len(), 14)
gtest.Assert(a1.Merge(s5).Len(), 16)
gtest.Assert(a1.Merge(s6).Len(), 19)
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 TestSortedStrArray_Json(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []string{"a", "b", "d", "c"}
s2 := []string{"a", "b", "c", "d"}
a1 := garray.NewSortedStrArrayFrom(s1)
b1, err1 := json.Marshal(a1)
b2, err2 := json.Marshal(s1)
gtest.Assert(b1, b2)
gtest.Assert(err1, err2)
t.Assert(b1, b2)
t.Assert(err1, err2)
a2 := garray.NewSortedStrArray()
err1 = json.Unmarshal(b2, &a2)
gtest.Assert(a2.Slice(), s2)
gtest.Assert(a2.Interfaces(), s2)
t.Assert(a2.Slice(), s2)
t.Assert(a2.Interfaces(), s2)
var a3 garray.SortedStrArray
err := json.Unmarshal(b2, &a3)
gtest.Assert(err, nil)
gtest.Assert(a3.Slice(), s1)
gtest.Assert(a3.Interfaces(), s1)
t.Assert(err, nil)
t.Assert(a3.Slice(), s1)
t.Assert(a3.Interfaces(), s1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
type User struct {
Name string
Scores *garray.SortedStrArray
@ -499,111 +544,111 @@ func TestSortedStrArray_Json(t *testing.T) {
"Scores": []string{"A+", "A", "A"},
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
user := new(User)
err = json.Unmarshal(b, user)
gtest.Assert(err, nil)
gtest.Assert(user.Name, data["Name"])
gtest.Assert(user.Scores, []string{"A", "A", "A+"})
t.Assert(err, nil)
t.Assert(user.Name, data["Name"])
t.Assert(user.Scores, []string{"A", "A", "A+"})
})
}
func TestSortedStrArray_Iterator(t *testing.T) {
slice := g.SliceStr{"a", "b", "d", "c"}
array := garray.NewSortedStrArrayFrom(slice)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.Iterator(func(k int, v string) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorAsc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array.IteratorDesc(func(k int, v string) bool {
gtest.Assert(v, slice[k])
t.Assert(v, slice[k])
return true
})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.Iterator(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorAsc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
index := 0
array.IteratorDesc(func(k int, v string) bool {
index++
return false
})
gtest.Assert(index, 1)
t.Assert(index, 1)
})
}
func TestSortedStrArray_RemoveValue(t *testing.T) {
slice := g.SliceStr{"a", "b", "d", "c"}
array := garray.NewSortedStrArrayFrom(slice)
gtest.Case(t, func() {
gtest.Assert(array.RemoveValue("e"), false)
gtest.Assert(array.RemoveValue("b"), true)
gtest.Assert(array.RemoveValue("a"), true)
gtest.Assert(array.RemoveValue("c"), true)
gtest.Assert(array.RemoveValue("f"), false)
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 TestSortedStrArray_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Array *garray.SortedStrArray
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`["1","3","2"]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.SliceStr{"1", "2", "3"})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.SliceStr{"1", "2", "3"})
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"array": g.SliceStr{"1", "3", "2"},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.SliceStr{"1", "2", "3"})
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Array.Slice(), g.SliceStr{"1", "2", "3"})
})
}
func TestSortedStrArray_FilterEmpty(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedStrArrayFrom(g.SliceStr{"", "1", "2", "0"})
gtest.Assert(array.FilterEmpty(), g.SliceStr{"0", "1", "2"})
t.Assert(array.FilterEmpty(), g.SliceStr{"0", "1", "2"})
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := garray.NewSortedStrArrayFrom(g.SliceStr{"1", "2"})
gtest.Assert(array.FilterEmpty(), g.SliceStr{"1", "2"})
t.Assert(array.FilterEmpty(), g.SliceStr{"1", "2"})
})
}

View File

@ -9,18 +9,18 @@ import (
)
func Test_Gchan(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
ch := gchan.New(10)
gtest.Assert(ch.Cap(), 10)
gtest.Assert(ch.Push(1), nil)
gtest.Assert(ch.Len(), 1)
gtest.Assert(ch.Size(), 1)
t.Assert(ch.Cap(), 10)
t.Assert(ch.Push(1), nil)
t.Assert(ch.Len(), 1)
t.Assert(ch.Size(), 1)
ch.Pop()
gtest.Assert(ch.Len(), 0)
gtest.Assert(ch.Size(), 0)
t.Assert(ch.Len(), 0)
t.Assert(ch.Size(), 0)
ch.Close()
gtest.Assert(ch.Push(1), errors.New("channel is closed"))
t.Assert(ch.Push(1), errors.New("channel is closed"))
ch = gchan.New(0)
ch1 := gchan.New(0)
@ -32,7 +32,7 @@ func Test_Gchan(t *testing.T) {
ch1.Push(i)
break
}
gtest.Assert(v, i)
t.Assert(v, i)
i++
}
}()
@ -41,7 +41,7 @@ func Test_Gchan(t *testing.T) {
ch.Push(index)
}
ch.Close()
gtest.Assert(ch1.Pop(), 10)
t.Assert(ch1.Pop(), 10)
ch1.Close()
})
}

View File

@ -16,7 +16,7 @@ import (
)
// 检查链表长度
func checkListLen(t *testing.T, l *List, len int) bool {
func checkListLen(t *gtest.T, l *List, len int) bool {
if n := l.Len(); n != len {
t.Errorf("l.Len() = %d, want %d", n, len)
return false
@ -25,7 +25,7 @@ func checkListLen(t *testing.T, l *List, len int) bool {
}
// 检查指针地址
func checkListPointers(t *testing.T, l *List, es []*Element) {
func checkListPointers(t *gtest.T, l *List, es []*Element) {
if !checkListLen(t, l, len(es)) {
return
}
@ -80,87 +80,89 @@ func TestBasic(t *testing.T) {
}
func TestList(t *testing.T) {
l := New()
checkListPointers(t, l, []*Element{})
gtest.C(t, func(t *gtest.T) {
l := New()
checkListPointers(t, l, []*Element{})
// Single element list
e := l.PushFront("a")
checkListPointers(t, l, []*Element{e})
l.MoveToFront(e)
checkListPointers(t, l, []*Element{e})
l.MoveToBack(e)
checkListPointers(t, l, []*Element{e})
l.Remove(e)
checkListPointers(t, l, []*Element{})
// Bigger list
e2 := l.PushFront(2)
e1 := l.PushFront(1)
e3 := l.PushBack(3)
e4 := l.PushBack("banana")
checkListPointers(t, l, []*Element{e1, e2, e3, e4})
l.Remove(e2)
checkListPointers(t, l, []*Element{e1, e3, e4})
l.MoveToFront(e3) // move from middle
checkListPointers(t, l, []*Element{e3, e1, e4})
l.MoveToFront(e1)
l.MoveToBack(e3) // move from middle
checkListPointers(t, l, []*Element{e1, e4, e3})
l.MoveToFront(e3) // move from back
checkListPointers(t, l, []*Element{e3, e1, e4})
l.MoveToFront(e3) // should be no-op
checkListPointers(t, l, []*Element{e3, e1, e4})
l.MoveToBack(e3) // move from front
checkListPointers(t, l, []*Element{e1, e4, e3})
l.MoveToBack(e3) // should be no-op
checkListPointers(t, l, []*Element{e1, e4, e3})
e2 = l.InsertBefore(e1, 2) // insert before front
checkListPointers(t, l, []*Element{e2, e1, e4, e3})
l.Remove(e2)
e2 = l.InsertBefore(e4, 2) // insert before middle
checkListPointers(t, l, []*Element{e1, e2, e4, e3})
l.Remove(e2)
e2 = l.InsertBefore(e3, 2) // insert before back
checkListPointers(t, l, []*Element{e1, e4, e2, e3})
l.Remove(e2)
e2 = l.InsertAfter(e1, 2) // insert after front
checkListPointers(t, l, []*Element{e1, e2, e4, e3})
l.Remove(e2)
e2 = l.InsertAfter(e4, 2) // insert after middle
checkListPointers(t, l, []*Element{e1, e4, e2, e3})
l.Remove(e2)
e2 = l.InsertAfter(e3, 2) // insert after back
checkListPointers(t, l, []*Element{e1, e4, e3, e2})
l.Remove(e2)
// Check standard iteration.
sum := 0
for e := l.Front(); e != nil; e = e.Next() {
if i, ok := e.Value.(int); ok {
sum += i
}
}
if sum != 4 {
t.Errorf("sum over l = %d, want 4", sum)
}
// Clear all elements by iterating
var next *Element
for e := l.Front(); e != nil; e = next {
next = e.Next()
// Single element list
e := l.PushFront("a")
checkListPointers(t, l, []*Element{e})
l.MoveToFront(e)
checkListPointers(t, l, []*Element{e})
l.MoveToBack(e)
checkListPointers(t, l, []*Element{e})
l.Remove(e)
}
checkListPointers(t, l, []*Element{})
checkListPointers(t, l, []*Element{})
// Bigger list
e2 := l.PushFront(2)
e1 := l.PushFront(1)
e3 := l.PushBack(3)
e4 := l.PushBack("banana")
checkListPointers(t, l, []*Element{e1, e2, e3, e4})
l.Remove(e2)
checkListPointers(t, l, []*Element{e1, e3, e4})
l.MoveToFront(e3) // move from middle
checkListPointers(t, l, []*Element{e3, e1, e4})
l.MoveToFront(e1)
l.MoveToBack(e3) // move from middle
checkListPointers(t, l, []*Element{e1, e4, e3})
l.MoveToFront(e3) // move from back
checkListPointers(t, l, []*Element{e3, e1, e4})
l.MoveToFront(e3) // should be no-op
checkListPointers(t, l, []*Element{e3, e1, e4})
l.MoveToBack(e3) // move from front
checkListPointers(t, l, []*Element{e1, e4, e3})
l.MoveToBack(e3) // should be no-op
checkListPointers(t, l, []*Element{e1, e4, e3})
e2 = l.InsertBefore(e1, 2) // insert before front
checkListPointers(t, l, []*Element{e2, e1, e4, e3})
l.Remove(e2)
e2 = l.InsertBefore(e4, 2) // insert before middle
checkListPointers(t, l, []*Element{e1, e2, e4, e3})
l.Remove(e2)
e2 = l.InsertBefore(e3, 2) // insert before back
checkListPointers(t, l, []*Element{e1, e4, e2, e3})
l.Remove(e2)
e2 = l.InsertAfter(e1, 2) // insert after front
checkListPointers(t, l, []*Element{e1, e2, e4, e3})
l.Remove(e2)
e2 = l.InsertAfter(e4, 2) // insert after middle
checkListPointers(t, l, []*Element{e1, e4, e2, e3})
l.Remove(e2)
e2 = l.InsertAfter(e3, 2) // insert after back
checkListPointers(t, l, []*Element{e1, e4, e3, e2})
l.Remove(e2)
// Check standard iteration.
sum := 0
for e := l.Front(); e != nil; e = e.Next() {
if i, ok := e.Value.(int); ok {
sum += i
}
}
if sum != 4 {
t.Errorf("sum over l = %d, want 4", sum)
}
// Clear all elements by iterating
var next *Element
for e := l.Front(); e != nil; e = next {
next = e.Next()
l.Remove(e)
}
checkListPointers(t, l, []*Element{})
})
}
func checkList(t *testing.T, l *List, es []interface{}) {
func checkList(t *gtest.T, l *List, es []interface{}) {
if !checkListLen(t, l, len(es)) {
return
}
@ -193,60 +195,64 @@ func checkList(t *testing.T, l *List, es []interface{}) {
}
func TestExtending(t *testing.T) {
l1 := New()
l2 := New()
gtest.C(t, func(t *gtest.T) {
l1 := New()
l2 := New()
l1.PushBack(1)
l1.PushBack(2)
l1.PushBack(3)
l1.PushBack(1)
l1.PushBack(2)
l1.PushBack(3)
l2.PushBack(4)
l2.PushBack(5)
l2.PushBack(4)
l2.PushBack(5)
l3 := New()
l3.PushBackList(l1)
checkList(t, l3, []interface{}{1, 2, 3})
l3.PushBackList(l2)
checkList(t, l3, []interface{}{1, 2, 3, 4, 5})
l3 := New()
l3.PushBackList(l1)
checkList(t, l3, []interface{}{1, 2, 3})
l3.PushBackList(l2)
checkList(t, l3, []interface{}{1, 2, 3, 4, 5})
l3 = New()
l3.PushFrontList(l2)
checkList(t, l3, []interface{}{4, 5})
l3.PushFrontList(l1)
checkList(t, l3, []interface{}{1, 2, 3, 4, 5})
l3 = New()
l3.PushFrontList(l2)
checkList(t, l3, []interface{}{4, 5})
l3.PushFrontList(l1)
checkList(t, l3, []interface{}{1, 2, 3, 4, 5})
checkList(t, l1, []interface{}{1, 2, 3})
checkList(t, l2, []interface{}{4, 5})
checkList(t, l1, []interface{}{1, 2, 3})
checkList(t, l2, []interface{}{4, 5})
l3 = New()
l3.PushBackList(l1)
checkList(t, l3, []interface{}{1, 2, 3})
l3.PushBackList(l3)
checkList(t, l3, []interface{}{1, 2, 3, 1, 2, 3})
l3 = New()
l3.PushBackList(l1)
checkList(t, l3, []interface{}{1, 2, 3})
l3.PushBackList(l3)
checkList(t, l3, []interface{}{1, 2, 3, 1, 2, 3})
l3 = New()
l3.PushFrontList(l1)
checkList(t, l3, []interface{}{1, 2, 3})
l3.PushFrontList(l3)
checkList(t, l3, []interface{}{1, 2, 3, 1, 2, 3})
l3 = New()
l3.PushFrontList(l1)
checkList(t, l3, []interface{}{1, 2, 3})
l3.PushFrontList(l3)
checkList(t, l3, []interface{}{1, 2, 3, 1, 2, 3})
l3 = New()
l1.PushBackList(l3)
checkList(t, l1, []interface{}{1, 2, 3})
l1.PushFrontList(l3)
checkList(t, l1, []interface{}{1, 2, 3})
l3 = New()
l1.PushBackList(l3)
checkList(t, l1, []interface{}{1, 2, 3})
l1.PushFrontList(l3)
checkList(t, l1, []interface{}{1, 2, 3})
})
}
func TestRemove(t *testing.T) {
l := New()
e1 := l.PushBack(1)
e2 := l.PushBack(2)
checkListPointers(t, l, []*Element{e1, e2})
//e := l.Front()
//l.Remove(e)
//checkListPointers(t, l, []*Element{e2})
//l.Remove(e)
//checkListPointers(t, l, []*Element{e2})
gtest.C(t, func(t *gtest.T) {
l := New()
e1 := l.PushBack(1)
e2 := l.PushBack(2)
checkListPointers(t, l, []*Element{e1, e2})
//e := l.Front()
//l.Remove(e)
//checkListPointers(t, l, []*Element{e2})
//l.Remove(e)
//checkListPointers(t, l, []*Element{e2})
})
}
func TestIssue4103(t *testing.T) {
@ -289,375 +295,416 @@ func TestIssue6349(t *testing.T) {
}
func TestMove(t *testing.T) {
l := New()
e1 := l.PushBack(1)
e2 := l.PushBack(2)
e3 := l.PushBack(3)
e4 := l.PushBack(4)
gtest.C(t, func(t *gtest.T) {
l := New()
e1 := l.PushBack(1)
e2 := l.PushBack(2)
e3 := l.PushBack(3)
e4 := l.PushBack(4)
l.MoveAfter(e3, e3)
checkListPointers(t, l, []*Element{e1, e2, e3, e4})
l.MoveBefore(e2, e2)
checkListPointers(t, l, []*Element{e1, e2, e3, e4})
l.MoveAfter(e3, e3)
checkListPointers(t, l, []*Element{e1, e2, e3, e4})
l.MoveBefore(e2, e2)
checkListPointers(t, l, []*Element{e1, e2, e3, e4})
l.MoveAfter(e3, e2)
checkListPointers(t, l, []*Element{e1, e2, e3, e4})
l.MoveBefore(e2, e3)
checkListPointers(t, l, []*Element{e1, e2, e3, e4})
l.MoveAfter(e3, e2)
checkListPointers(t, l, []*Element{e1, e2, e3, e4})
l.MoveBefore(e2, e3)
checkListPointers(t, l, []*Element{e1, e2, e3, e4})
l.MoveBefore(e2, e4)
checkListPointers(t, l, []*Element{e1, e3, e2, e4})
e2, e3 = e3, e2
l.MoveBefore(e2, e4)
checkListPointers(t, l, []*Element{e1, e3, e2, e4})
e2, e3 = e3, e2
l.MoveBefore(e4, e1)
checkListPointers(t, l, []*Element{e4, e1, e2, e3})
e1, e2, e3, e4 = e4, e1, e2, e3
l.MoveBefore(e4, e1)
checkListPointers(t, l, []*Element{e4, e1, e2, e3})
e1, e2, e3, e4 = e4, e1, e2, e3
l.MoveAfter(e4, e1)
checkListPointers(t, l, []*Element{e1, e4, e2, e3})
e2, e3, e4 = e4, e2, e3
l.MoveAfter(e4, e1)
checkListPointers(t, l, []*Element{e1, e4, e2, e3})
e2, e3, e4 = e4, e2, e3
l.MoveAfter(e2, e3)
checkListPointers(t, l, []*Element{e1, e3, e2, e4})
e2, e3 = e3, e2
l.MoveAfter(e2, e3)
checkListPointers(t, l, []*Element{e1, e3, e2, e4})
e2, e3 = e3, e2
})
}
// Test PushFront, PushBack, PushFrontList, PushBackList with uninitialized List
func TestZeroList(t *testing.T) {
var l1 = New()
l1.PushFront(1)
checkList(t, l1, []interface{}{1})
gtest.C(t, func(t *gtest.T) {
var l1 = New()
l1.PushFront(1)
checkList(t, l1, []interface{}{1})
var l2 = New()
l2.PushBack(1)
checkList(t, l2, []interface{}{1})
var l2 = New()
l2.PushBack(1)
checkList(t, l2, []interface{}{1})
var l3 = New()
l3.PushFrontList(l1)
checkList(t, l3, []interface{}{1})
var l3 = New()
l3.PushFrontList(l1)
checkList(t, l3, []interface{}{1})
var l4 = New()
l4.PushBackList(l2)
checkList(t, l4, []interface{}{1})
var l4 = New()
l4.PushBackList(l2)
checkList(t, l4, []interface{}{1})
})
}
// Test that a list l is not modified when calling InsertBefore with a mark that is not an element of l.
func TestInsertBeforeUnknownMark(t *testing.T) {
l := New()
l.PushBack(1)
l.PushBack(2)
l.PushBack(3)
l.InsertBefore(new(Element), 1)
checkList(t, l, []interface{}{1, 2, 3})
gtest.C(t, func(t *gtest.T) {
l := New()
l.PushBack(1)
l.PushBack(2)
l.PushBack(3)
l.InsertBefore(new(Element), 1)
checkList(t, l, []interface{}{1, 2, 3})
})
}
// Test that a list l is not modified when calling InsertAfter with a mark that is not an element of l.
func TestInsertAfterUnknownMark(t *testing.T) {
l := New()
l.PushBack(1)
l.PushBack(2)
l.PushBack(3)
l.InsertAfter(new(Element), 1)
checkList(t, l, []interface{}{1, 2, 3})
gtest.C(t, func(t *gtest.T) {
l := New()
l.PushBack(1)
l.PushBack(2)
l.PushBack(3)
l.InsertAfter(new(Element), 1)
checkList(t, l, []interface{}{1, 2, 3})
})
}
// Test that a list l is not modified when calling MoveAfter or MoveBefore with a mark that is not an element of l.
func TestMoveUnknownMark(t *testing.T) {
l1 := New()
e1 := l1.PushBack(1)
gtest.C(t, func(t *gtest.T) {
l1 := New()
e1 := l1.PushBack(1)
l2 := New()
e2 := l2.PushBack(2)
l2 := New()
e2 := l2.PushBack(2)
l1.MoveAfter(e1, e2)
checkList(t, l1, []interface{}{1})
checkList(t, l2, []interface{}{2})
l1.MoveAfter(e1, e2)
checkList(t, l1, []interface{}{1})
checkList(t, l2, []interface{}{2})
l1.MoveBefore(e1, e2)
checkList(t, l1, []interface{}{1})
checkList(t, l2, []interface{}{2})
l1.MoveBefore(e1, e2)
checkList(t, l1, []interface{}{1})
checkList(t, l2, []interface{}{2})
})
}
func TestList_RemoveAll(t *testing.T) {
l := New()
l.PushBack(1)
l.RemoveAll()
checkList(t, l, []interface{}{})
l.PushBack(2)
checkList(t, l, []interface{}{2})
gtest.C(t, func(t *gtest.T) {
l := New()
l.PushBack(1)
l.RemoveAll()
checkList(t, l, []interface{}{})
l.PushBack(2)
checkList(t, l, []interface{}{2})
})
}
func TestList_PushFronts(t *testing.T) {
l := New()
a1 := []interface{}{1, 2}
l.PushFronts(a1)
checkList(t, l, []interface{}{2, 1})
a1 = []interface{}{3, 4, 5}
l.PushFronts(a1)
checkList(t, l, []interface{}{5, 4, 3, 2, 1})
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2}
l.PushFronts(a1)
checkList(t, l, []interface{}{2, 1})
a1 = []interface{}{3, 4, 5}
l.PushFronts(a1)
checkList(t, l, []interface{}{5, 4, 3, 2, 1})
})
}
func TestList_PushBacks(t *testing.T) {
l := New()
a1 := []interface{}{1, 2}
l.PushBacks(a1)
checkList(t, l, []interface{}{1, 2})
a1 = []interface{}{3, 4, 5}
l.PushBacks(a1)
checkList(t, l, []interface{}{1, 2, 3, 4, 5})
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2}
l.PushBacks(a1)
checkList(t, l, []interface{}{1, 2})
a1 = []interface{}{3, 4, 5}
l.PushBacks(a1)
checkList(t, l, []interface{}{1, 2, 3, 4, 5})
})
}
func TestList_PopBacks(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
a2 := []interface{}{"a", "c", "b", "e"}
l.PushFronts(a1)
i1 := l.PopBacks(2)
gtest.Assert(i1, []interface{}{1, 2})
t.Assert(i1, []interface{}{1, 2})
l.PushBacks(a2) //4.3,a,c,b,e
i1 = l.PopBacks(3)
gtest.Assert(i1, []interface{}{"e", "b", "c"})
t.Assert(i1, []interface{}{"e", "b", "c"})
})
}
func TestList_PopFronts(t *testing.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.PopFronts(2)
gtest.Assert(i1, []interface{}{4, 3})
gtest.Assert(l.Len(), 2)
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.PopFronts(2)
t.Assert(i1, []interface{}{4, 3})
t.Assert(l.Len(), 2)
})
}
func TestList_PopBackAll(t *testing.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.PopBackAll()
gtest.Assert(i1, []interface{}{1, 2, 3, 4})
gtest.Assert(l.Len(), 0)
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.PopBackAll()
t.Assert(i1, []interface{}{1, 2, 3, 4})
t.Assert(l.Len(), 0)
})
}
func TestList_PopFrontAll(t *testing.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.PopFrontAll()
gtest.Assert(i1, []interface{}{4, 3, 2, 1})
gtest.Assert(l.Len(), 0)
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.PopFrontAll()
t.Assert(i1, []interface{}{4, 3, 2, 1})
t.Assert(l.Len(), 0)
})
}
func TestList_FrontAll(t *testing.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.FrontAll()
gtest.Assert(i1, []interface{}{4, 3, 2, 1})
gtest.Assert(l.Len(), 4)
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.FrontAll()
t.Assert(i1, []interface{}{4, 3, 2, 1})
t.Assert(l.Len(), 4)
})
}
func TestList_BackAll(t *testing.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.BackAll()
gtest.Assert(i1, []interface{}{1, 2, 3, 4})
gtest.Assert(l.Len(), 4)
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.BackAll()
t.Assert(i1, []interface{}{1, 2, 3, 4})
t.Assert(l.Len(), 4)
})
}
func TestList_FrontValue(t *testing.T) {
l := New()
l2 := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.FrontValue()
gtest.Assert(gconv.Int(i1), 4)
gtest.Assert(l.Len(), 4)
gtest.C(t, func(t *gtest.T) {
l := New()
l2 := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.FrontValue()
t.Assert(gconv.Int(i1), 4)
t.Assert(l.Len(), 4)
i1 = l2.FrontValue()
gtest.Assert(i1, nil)
i1 = l2.FrontValue()
t.Assert(i1, nil)
})
}
func TestList_BackValue(t *testing.T) {
l := New()
l2 := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.BackValue()
gtest.Assert(gconv.Int(i1), 1)
gtest.Assert(l.Len(), 4)
i1 = l2.FrontValue()
gtest.Assert(i1, nil)
gtest.C(t, func(t *gtest.T) {
l := New()
l2 := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
i1 := l.BackValue()
t.Assert(gconv.Int(i1), 1)
t.Assert(l.Len(), 4)
i1 = l2.FrontValue()
t.Assert(i1, nil)
})
}
func TestList_Back(t *testing.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
e1 := l.Back()
gtest.Assert(e1.Value, 1)
gtest.Assert(l.Len(), 4)
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
e1 := l.Back()
t.Assert(e1.Value, 1)
t.Assert(l.Len(), 4)
})
}
func TestList_Size(t *testing.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
gtest.Assert(l.Size(), 4)
l.PopFront()
gtest.Assert(l.Size(), 3)
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
t.Assert(l.Size(), 4)
l.PopFront()
t.Assert(l.Size(), 3)
})
}
func TestList_Removes(t *testing.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
e1 := l.Back()
l.Removes([]*Element{e1})
gtest.Assert(l.Len(), 3)
e2 := l.Back()
l.Removes([]*Element{e2})
gtest.Assert(l.Len(), 2)
checkList(t, l, []interface{}{4, 3})
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
e1 := l.Back()
l.Removes([]*Element{e1})
t.Assert(l.Len(), 3)
e2 := l.Back()
l.Removes([]*Element{e2})
t.Assert(l.Len(), 2)
checkList(t, l, []interface{}{4, 3})
})
}
func TestList_Clear(t *testing.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
l.Clear()
gtest.Assert(l.Len(), 0)
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
l.Clear()
t.Assert(l.Len(), 0)
})
}
func TestList_IteratorAsc(t *testing.T) {
l := New()
a1 := []interface{}{1, 2, 5, 6, 3, 4}
l.PushFronts(a1)
e1 := l.Back()
fun1 := func(e *Element) bool {
if gconv.Int(e1.Value) > 2 {
return true
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 5, 6, 3, 4}
l.PushFronts(a1)
e1 := l.Back()
fun1 := func(e *Element) bool {
if gconv.Int(e1.Value) > 2 {
return true
}
return false
}
return false
}
checkList(t, l, []interface{}{4, 3, 6, 5, 2, 1})
l.IteratorAsc(fun1)
checkList(t, l, []interface{}{4, 3, 6, 5, 2, 1})
checkList(t, l, []interface{}{4, 3, 6, 5, 2, 1})
l.IteratorAsc(fun1)
checkList(t, l, []interface{}{4, 3, 6, 5, 2, 1})
})
}
func TestList_IteratorDesc(t *testing.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
e1 := l.Back()
fun1 := func(e *Element) bool {
if gconv.Int(e1.Value) > 6 {
return true
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{1, 2, 3, 4}
l.PushFronts(a1)
e1 := l.Back()
fun1 := func(e *Element) bool {
if gconv.Int(e1.Value) > 6 {
return true
}
return false
}
return false
}
l.IteratorDesc(fun1)
gtest.Assert(l.Len(), 4)
checkList(t, l, []interface{}{4, 3, 2, 1})
l.IteratorDesc(fun1)
t.Assert(l.Len(), 4)
checkList(t, l, []interface{}{4, 3, 2, 1})
})
}
func TestList_Iterator(t *testing.T) {
l := New()
a1 := []interface{}{"a", "b", "c", "d", "e"}
l.PushFronts(a1)
e1 := l.Back()
fun1 := func(e *Element) bool {
if gconv.String(e1.Value) > "c" {
return true
gtest.C(t, func(t *gtest.T) {
l := New()
a1 := []interface{}{"a", "b", "c", "d", "e"}
l.PushFronts(a1)
e1 := l.Back()
fun1 := func(e *Element) bool {
if gconv.String(e1.Value) > "c" {
return true
}
return false
}
return false
}
checkList(t, l, []interface{}{"e", "d", "c", "b", "a"})
l.Iterator(fun1)
checkList(t, l, []interface{}{"e", "d", "c", "b", "a"})
checkList(t, l, []interface{}{"e", "d", "c", "b", "a"})
l.Iterator(fun1)
checkList(t, l, []interface{}{"e", "d", "c", "b", "a"})
})
}
func TestList_Join(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
l := NewFrom([]interface{}{1, 2, "a", `"b"`, `\c`})
gtest.Assert(l.Join(","), `1,2,"a","\"b\"","\\c"`)
gtest.Assert(l.Join("."), `1.2."a"."\"b\""."\\c"`)
t.Assert(l.Join(","), `1,2,"a","\"b\"","\\c"`)
t.Assert(l.Join("."), `1.2."a"."\"b\""."\\c"`)
})
}
func TestList_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
l := NewFrom([]interface{}{1, 2, "a", `"b"`, `\c`})
gtest.Assert(l.String(), `[1,2,"a","\"b\"","\\c"]`)
t.Assert(l.String(), `[1,2,"a","\"b\"","\\c"]`)
})
}
func TestList_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a := []interface{}{"a", "b", "c"}
l := New()
l.PushBacks(a)
b1, err1 := json.Marshal(l)
b2, err2 := json.Marshal(a)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a := []interface{}{"a", "b", "c"}
l := New()
b, err := json.Marshal(a)
gtest.Assert(err, nil)
t.Assert(err, nil)
err = json.Unmarshal(b, l)
gtest.Assert(err, nil)
gtest.Assert(l.FrontAll(), a)
t.Assert(err, nil)
t.Assert(l.FrontAll(), a)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var l List
a := []interface{}{"a", "b", "c"}
b, err := json.Marshal(a)
gtest.Assert(err, nil)
t.Assert(err, nil)
err = json.Unmarshal(b, &l)
gtest.Assert(err, nil)
gtest.Assert(l.FrontAll(), a)
t.Assert(err, nil)
t.Assert(l.FrontAll(), a)
})
}
func TestList_UnmarshalValue(t *testing.T) {
type T struct {
type TList struct {
Name string
List *List
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var tlist *TList
err := gconv.Struct(map[string]interface{}{
"name": "john",
"list": []byte(`[1,2,3]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.List.FrontAll(), []interface{}{1, 2, 3})
}, &tlist)
t.Assert(err, nil)
t.Assert(tlist.Name, "john")
t.Assert(tlist.List.FrontAll(), []interface{}{1, 2, 3})
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var tlist *TList
err := gconv.Struct(map[string]interface{}{
"name": "john",
"list": []interface{}{1, 2, 3},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.List.FrontAll(), []interface{}{1, 2, 3})
}, &tlist)
t.Assert(err, nil)
t.Assert(tlist.Name, "john")
t.Assert(tlist.List.FrontAll(), []interface{}{1, 2, 3})
})
}

View File

@ -18,109 +18,120 @@ func getValue() interface{} {
}
func Test_Map_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.New()
m.Set("key1", "val1")
gtest.Assert(m.Keys(), []interface{}{"key1"})
t.Assert(m.Keys(), []interface{}{"key1"})
gtest.Assert(m.Get("key1"), "val1")
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get("key1"), "val1")
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet("key2", "val2"), "val2")
gtest.Assert(m.SetIfNotExist("key2", "val2"), false)
t.Assert(m.GetOrSet("key2", "val2"), "val2")
t.Assert(m.SetIfNotExist("key2", "val2"), false)
gtest.Assert(m.SetIfNotExist("key3", "val3"), true)
t.Assert(m.SetIfNotExist("key3", "val3"), true)
gtest.Assert(m.Remove("key2"), "val2")
gtest.Assert(m.Contains("key2"), false)
t.Assert(m.Remove("key2"), "val2")
t.Assert(m.Contains("key2"), false)
gtest.AssertIN("key3", m.Keys())
gtest.AssertIN("key1", m.Keys())
gtest.AssertIN("val3", m.Values())
gtest.AssertIN("val1", m.Values())
t.AssertIN("key3", m.Keys())
t.AssertIN("key1", m.Keys())
t.AssertIN("val3", m.Values())
t.AssertIN("val1", m.Values())
m.Flip()
gtest.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val1": "key1"})
t.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val1": "key1"})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gmap.NewFrom(map[interface{}]interface{}{1: 1, "key1": "val1"})
gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
t.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
})
}
func Test_Map_Set_Fun(t *testing.T) {
m := gmap.New()
m.GetOrSetFunc("fun", getValue)
m.GetOrSetFuncLock("funlock", getValue)
gtest.Assert(m.Get("funlock"), 3)
gtest.Assert(m.Get("fun"), 3)
m.GetOrSetFunc("fun", getValue)
gtest.Assert(m.SetIfNotExistFunc("fun", getValue), false)
gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
gtest.C(t, func(t *gtest.T) {
m := gmap.New()
m.GetOrSetFunc("fun", getValue)
m.GetOrSetFuncLock("funlock", getValue)
t.Assert(m.Get("funlock"), 3)
t.Assert(m.Get("fun"), 3)
m.GetOrSetFunc("fun", getValue)
t.Assert(m.SetIfNotExistFunc("fun", getValue), false)
t.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
})
}
func Test_Map_Batch(t *testing.T) {
m := gmap.New()
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
gtest.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
gtest.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
gtest.C(t, func(t *gtest.T) {
m := gmap.New()
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
t.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
t.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
})
}
func Test_Map_Iterator(t *testing.T) {
expect := map[interface{}]interface{}{1: 1, "key1": "val1"}
gtest.C(t, func(t *gtest.T) {
expect := map[interface{}]interface{}{1: 1, "key1": "val1"}
m := gmap.NewFrom(expect)
m.Iterator(func(k interface{}, v interface{}) bool {
gtest.Assert(expect[k], v)
return true
m := gmap.NewFrom(expect)
m.Iterator(func(k interface{}, v interface{}) bool {
t.Assert(expect[k], v)
return true
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k interface{}, v interface{}) bool {
i++
return true
})
m.Iterator(func(k interface{}, v interface{}) bool {
j++
return false
})
t.Assert(i, 2)
t.Assert(j, 1)
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k interface{}, v interface{}) bool {
i++
return true
})
m.Iterator(func(k interface{}, v interface{}) bool {
j++
return false
})
gtest.Assert(i, 2)
gtest.Assert(j, 1)
}
func Test_Map_Lock(t *testing.T) {
expect := map[interface{}]interface{}{1: 1, "key1": "val1"}
m := gmap.NewFrom(expect)
m.LockFunc(func(m map[interface{}]interface{}) {
gtest.Assert(m, expect)
})
m.RLockFunc(func(m map[interface{}]interface{}) {
gtest.Assert(m, expect)
gtest.C(t, func(t *gtest.T) {
expect := map[interface{}]interface{}{1: 1, "key1": "val1"}
m := gmap.NewFrom(expect)
m.LockFunc(func(m map[interface{}]interface{}) {
t.Assert(m, expect)
})
m.RLockFunc(func(m map[interface{}]interface{}) {
t.Assert(m, expect)
})
})
}
func Test_Map_Clone(t *testing.T) {
//clone 方法是深克隆
m := gmap.NewFrom(map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
gtest.AssertIN(1, m_clone.Keys())
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gmap.NewFrom(map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
t.AssertIN(1, m_clone.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
gtest.AssertIN("key1", m.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
t.AssertIN("key1", m.Keys())
})
}
func Test_Map_Basic_Merge(t *testing.T) {
m1 := gmap.New()
m2 := gmap.New()
m1.Set("key1", "val1")
m2.Set("key2", "val2")
m1.Merge(m2)
gtest.Assert(m1.Map(), map[interface{}]interface{}{"key1": "val1", "key2": "val2"})
gtest.C(t, func(t *gtest.T) {
m1 := gmap.New()
m2 := gmap.New()
m1.Set("key1", "val1")
m2.Set("key2", "val2")
m1.Merge(m2)
t.Assert(m1.Map(), map[interface{}]interface{}{"key1": "val1", "key2": "val2"})
})
}

View File

@ -6,7 +6,7 @@ import (
"github.com/gogf/gf/container/gmap"
)
func Example_Normal_Basic() {
func Example_normalBasic() {
m := gmap.New()
//Add data
@ -61,7 +61,7 @@ func Example_Normal_Basic() {
fmt.Println(m.Size())
}
func Example_Normal_Merge() {
func Example_normalMerge() {
m1 := gmap.New()
m2 := gmap.New()
m1.Set("key1", "val1")

View File

@ -22,166 +22,181 @@ func anyAnyCallBack(int, interface{}) bool {
}
func Test_AnyAnyMap_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewAnyAnyMap()
m.Set(1, 1)
gtest.Assert(m.Get(1), 1)
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get(1), 1)
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet(2, "2"), "2")
gtest.Assert(m.SetIfNotExist(2, "2"), false)
t.Assert(m.GetOrSet(2, "2"), "2")
t.Assert(m.SetIfNotExist(2, "2"), false)
gtest.Assert(m.SetIfNotExist(3, 3), true)
t.Assert(m.SetIfNotExist(3, 3), true)
gtest.Assert(m.Remove(2), "2")
gtest.Assert(m.Contains(2), false)
t.Assert(m.Remove(2), "2")
t.Assert(m.Contains(2), false)
gtest.AssertIN(3, m.Keys())
gtest.AssertIN(1, m.Keys())
gtest.AssertIN(3, m.Values())
gtest.AssertIN(1, m.Values())
t.AssertIN(3, m.Keys())
t.AssertIN(1, m.Keys())
t.AssertIN(3, m.Values())
t.AssertIN(1, m.Values())
m.Flip()
gtest.Assert(m.Map(), map[interface{}]int{1: 1, 3: 3})
t.Assert(m.Map(), map[interface{}]int{1: 1, 3: 3})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gmap.NewAnyAnyMapFrom(map[interface{}]interface{}{1: 1, 2: "2"})
gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, 2: "2"})
t.Assert(m2.Map(), map[interface{}]interface{}{1: 1, 2: "2"})
})
}
func Test_AnyAnyMap_Set_Fun(t *testing.T) {
m := gmap.NewAnyAnyMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewAnyAnyMap()
m.GetOrSetFunc(1, getAny)
m.GetOrSetFuncLock(2, getAny)
gtest.Assert(m.Get(1), 123)
gtest.Assert(m.Get(2), 123)
m.GetOrSetFunc(1, getAny)
m.GetOrSetFuncLock(2, getAny)
t.Assert(m.Get(1), 123)
t.Assert(m.Get(2), 123)
gtest.Assert(m.SetIfNotExistFunc(1, getAny), false)
gtest.Assert(m.SetIfNotExistFunc(3, getAny), true)
t.Assert(m.SetIfNotExistFunc(1, getAny), false)
t.Assert(m.SetIfNotExistFunc(3, getAny), true)
gtest.Assert(m.SetIfNotExistFuncLock(2, getAny), false)
gtest.Assert(m.SetIfNotExistFuncLock(4, getAny), true)
t.Assert(m.SetIfNotExistFuncLock(2, getAny), false)
t.Assert(m.SetIfNotExistFuncLock(4, getAny), true)
})
}
func Test_AnyAnyMap_Batch(t *testing.T) {
m := gmap.NewAnyAnyMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewAnyAnyMap()
m.Sets(map[interface{}]interface{}{1: 1, 2: "2", 3: 3})
gtest.Assert(m.Map(), map[interface{}]interface{}{1: 1, 2: "2", 3: 3})
m.Removes([]interface{}{1, 2})
gtest.Assert(m.Map(), map[interface{}]interface{}{3: 3})
m.Sets(map[interface{}]interface{}{1: 1, 2: "2", 3: 3})
t.Assert(m.Map(), map[interface{}]interface{}{1: 1, 2: "2", 3: 3})
m.Removes([]interface{}{1, 2})
t.Assert(m.Map(), map[interface{}]interface{}{3: 3})
})
}
func Test_AnyAnyMap_Iterator(t *testing.T) {
expect := map[interface{}]interface{}{1: 1, 2: "2"}
m := gmap.NewAnyAnyMapFrom(expect)
m.Iterator(func(k interface{}, v interface{}) bool {
gtest.Assert(expect[k], v)
return true
gtest.C(t, func(t *gtest.T) {
expect := map[interface{}]interface{}{1: 1, 2: "2"}
m := gmap.NewAnyAnyMapFrom(expect)
m.Iterator(func(k interface{}, v interface{}) bool {
t.Assert(expect[k], v)
return true
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k interface{}, v interface{}) bool {
i++
return true
})
m.Iterator(func(k interface{}, v interface{}) bool {
j++
return false
})
t.Assert(i, "2")
t.Assert(j, 1)
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k interface{}, v interface{}) bool {
i++
return true
})
m.Iterator(func(k interface{}, v interface{}) bool {
j++
return false
})
gtest.Assert(i, "2")
gtest.Assert(j, 1)
}
func Test_AnyAnyMap_Lock(t *testing.T) {
expect := map[interface{}]interface{}{1: 1, 2: "2"}
m := gmap.NewAnyAnyMapFrom(expect)
m.LockFunc(func(m map[interface{}]interface{}) {
gtest.Assert(m, expect)
})
m.RLockFunc(func(m map[interface{}]interface{}) {
gtest.Assert(m, expect)
gtest.C(t, func(t *gtest.T) {
expect := map[interface{}]interface{}{1: 1, 2: "2"}
m := gmap.NewAnyAnyMapFrom(expect)
m.LockFunc(func(m map[interface{}]interface{}) {
t.Assert(m, expect)
})
m.RLockFunc(func(m map[interface{}]interface{}) {
t.Assert(m, expect)
})
})
}
func Test_AnyAnyMap_Clone(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gmap.NewAnyAnyMapFrom(map[interface{}]interface{}{1: 1, 2: "2"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
gtest.AssertIN(1, m_clone.Keys())
t.AssertIN(1, m_clone.Keys())
m_clone.Remove(2)
//修改clone map,原 map 不影响
gtest.AssertIN(2, m.Keys())
t.AssertIN(2, m.Keys())
})
}
func Test_AnyAnyMap_Merge(t *testing.T) {
m1 := gmap.NewAnyAnyMap()
m2 := gmap.NewAnyAnyMap()
m1.Set(1, 1)
m2.Set(2, "2")
m1.Merge(m2)
gtest.Assert(m1.Map(), map[interface{}]interface{}{1: 1, 2: "2"})
gtest.C(t, func(t *gtest.T) {
m1 := gmap.NewAnyAnyMap()
m2 := gmap.NewAnyAnyMap()
m1.Set(1, 1)
m2.Set(2, "2")
m1.Merge(m2)
t.Assert(m1.Map(), map[interface{}]interface{}{1: 1, 2: "2"})
})
}
func Test_AnyAnyMap_Map(t *testing.T) {
m := gmap.NewAnyAnyMap()
m.Set(1, 0)
m.Set(2, 2)
gtest.Assert(m.Get(1), 0)
gtest.Assert(m.Get(2), 2)
data := m.Map()
gtest.Assert(data[1], 0)
gtest.Assert(data[2], 2)
data[3] = 3
gtest.Assert(m.Get(3), 3)
m.Set(4, 4)
gtest.Assert(data[4], 4)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewAnyAnyMap()
m.Set(1, 0)
m.Set(2, 2)
t.Assert(m.Get(1), 0)
t.Assert(m.Get(2), 2)
data := m.Map()
t.Assert(data[1], 0)
t.Assert(data[2], 2)
data[3] = 3
t.Assert(m.Get(3), 3)
m.Set(4, 4)
t.Assert(data[4], 4)
})
}
func Test_AnyAnyMap_MapCopy(t *testing.T) {
m := gmap.NewAnyAnyMap()
m.Set(1, 0)
m.Set(2, 2)
gtest.Assert(m.Get(1), 0)
gtest.Assert(m.Get(2), 2)
data := m.MapCopy()
gtest.Assert(data[1], 0)
gtest.Assert(data[2], 2)
data[3] = 3
gtest.Assert(m.Get(3), nil)
m.Set(4, 4)
gtest.Assert(data[4], nil)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewAnyAnyMap()
m.Set(1, 0)
m.Set(2, 2)
t.Assert(m.Get(1), 0)
t.Assert(m.Get(2), 2)
data := m.MapCopy()
t.Assert(data[1], 0)
t.Assert(data[2], 2)
data[3] = 3
t.Assert(m.Get(3), nil)
m.Set(4, 4)
t.Assert(data[4], nil)
})
}
func Test_AnyAnyMap_FilterEmpty(t *testing.T) {
m := gmap.NewAnyAnyMap()
m.Set(1, 0)
m.Set(2, 2)
gtest.Assert(m.Get(1), 0)
gtest.Assert(m.Get(2), 2)
m.FilterEmpty()
gtest.Assert(m.Get(1), nil)
gtest.Assert(m.Get(2), 2)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewAnyAnyMap()
m.Set(1, 0)
m.Set(2, 2)
t.Assert(m.Get(1), 0)
t.Assert(m.Get(2), 2)
m.FilterEmpty()
t.Assert(m.Get(1), nil)
t.Assert(m.Get(2), 2)
})
}
func Test_AnyAnyMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
@ -189,125 +204,125 @@ func Test_AnyAnyMap_Json(t *testing.T) {
m1 := gmap.NewAnyAnyMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(gconv.Map(data))
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
t.Assert(err, nil)
m := gmap.New()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
t.Assert(err, nil)
var m gmap.Map
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
}
func Test_AnyAnyMap_Pop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewAnyAnyMapFrom(g.MapAnyAny{
"k1": "v1",
"k2": "v2",
})
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
k1, v1 := m.Pop()
gtest.AssertIN(k1, g.Slice{"k1", "k2"})
gtest.AssertIN(v1, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 1)
t.AssertIN(k1, g.Slice{"k1", "k2"})
t.AssertIN(v1, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 1)
k2, v2 := m.Pop()
gtest.AssertIN(k2, g.Slice{"k1", "k2"})
gtest.AssertIN(v2, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 0)
t.AssertIN(k2, g.Slice{"k1", "k2"})
t.AssertIN(v2, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 0)
gtest.AssertNE(k1, k2)
gtest.AssertNE(v1, v2)
t.AssertNE(k1, k2)
t.AssertNE(v1, v2)
})
}
func Test_AnyAnyMap_Pops(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewAnyAnyMapFrom(g.MapAnyAny{
"k1": "v1",
"k2": "v2",
"k3": "v3",
})
gtest.Assert(m.Size(), 3)
t.Assert(m.Size(), 3)
kArray := garray.New()
vArray := garray.New()
for k, v := range m.Pops(1) {
gtest.AssertIN(k, g.Slice{"k1", "k2", "k3"})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
for k, v := range m.Pops(2) {
gtest.AssertIN(k, g.Slice{"k1", "k2", "k3"})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 0)
t.Assert(m.Size(), 0)
gtest.Assert(kArray.Unique().Len(), 3)
gtest.Assert(vArray.Unique().Len(), 3)
t.Assert(kArray.Unique().Len(), 3)
t.Assert(vArray.Unique().Len(), 3)
})
}
func TestAnyAnyMap_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Map *gmap.Map
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"k1":"v1","k2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("k1"), "v1")
t.Assert(v.Map.Get("k2"), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.Map{
"k1": "v1",
"k2": "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("k1"), "v1")
t.Assert(v.Map.Get("k2"), "v2")
})
}

View File

@ -24,161 +24,178 @@ func intAnyCallBack(int, interface{}) bool {
return true
}
func Test_IntAnyMap_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntAnyMap()
m.Set(1, 1)
gtest.Assert(m.Get(1), 1)
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get(1), 1)
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet(2, "2"), "2")
gtest.Assert(m.SetIfNotExist(2, "2"), false)
t.Assert(m.GetOrSet(2, "2"), "2")
t.Assert(m.SetIfNotExist(2, "2"), false)
gtest.Assert(m.SetIfNotExist(3, 3), true)
t.Assert(m.SetIfNotExist(3, 3), true)
gtest.Assert(m.Remove(2), "2")
gtest.Assert(m.Contains(2), false)
t.Assert(m.Remove(2), "2")
t.Assert(m.Contains(2), false)
gtest.AssertIN(3, m.Keys())
gtest.AssertIN(1, m.Keys())
gtest.AssertIN(3, m.Values())
gtest.AssertIN(1, m.Values())
t.AssertIN(3, m.Keys())
t.AssertIN(1, m.Keys())
t.AssertIN(3, m.Values())
t.AssertIN(1, m.Values())
m.Flip()
gtest.Assert(m.Map(), map[interface{}]int{1: 1, 3: 3})
t.Assert(m.Map(), map[interface{}]int{1: 1, 3: 3})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gmap.NewIntAnyMapFrom(map[int]interface{}{1: 1, 2: "2"})
gtest.Assert(m2.Map(), map[int]interface{}{1: 1, 2: "2"})
t.Assert(m2.Map(), map[int]interface{}{1: 1, 2: "2"})
})
}
func Test_IntAnyMap_Set_Fun(t *testing.T) {
m := gmap.NewIntAnyMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntAnyMap()
m.GetOrSetFunc(1, getAny)
m.GetOrSetFuncLock(2, getAny)
gtest.Assert(m.Get(1), 123)
gtest.Assert(m.Get(2), 123)
m.GetOrSetFunc(1, getAny)
m.GetOrSetFuncLock(2, getAny)
t.Assert(m.Get(1), 123)
t.Assert(m.Get(2), 123)
gtest.Assert(m.SetIfNotExistFunc(1, getAny), false)
gtest.Assert(m.SetIfNotExistFunc(3, getAny), true)
gtest.Assert(m.SetIfNotExistFuncLock(2, getAny), false)
gtest.Assert(m.SetIfNotExistFuncLock(4, getAny), true)
t.Assert(m.SetIfNotExistFunc(1, getAny), false)
t.Assert(m.SetIfNotExistFunc(3, getAny), true)
t.Assert(m.SetIfNotExistFuncLock(2, getAny), false)
t.Assert(m.SetIfNotExistFuncLock(4, getAny), true)
})
}
func Test_IntAnyMap_Batch(t *testing.T) {
m := gmap.NewIntAnyMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntAnyMap()
m.Sets(map[int]interface{}{1: 1, 2: "2", 3: 3})
gtest.Assert(m.Map(), map[int]interface{}{1: 1, 2: "2", 3: 3})
m.Removes([]int{1, 2})
gtest.Assert(m.Map(), map[int]interface{}{3: 3})
m.Sets(map[int]interface{}{1: 1, 2: "2", 3: 3})
t.Assert(m.Map(), map[int]interface{}{1: 1, 2: "2", 3: 3})
m.Removes([]int{1, 2})
t.Assert(m.Map(), map[int]interface{}{3: 3})
})
}
func Test_IntAnyMap_Iterator(t *testing.T) {
expect := map[int]interface{}{1: 1, 2: "2"}
m := gmap.NewIntAnyMapFrom(expect)
m.Iterator(func(k int, v interface{}) bool {
gtest.Assert(expect[k], v)
return true
gtest.C(t, func(t *gtest.T) {
expect := map[int]interface{}{1: 1, 2: "2"}
m := gmap.NewIntAnyMapFrom(expect)
m.Iterator(func(k int, v interface{}) bool {
t.Assert(expect[k], v)
return true
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k int, v interface{}) bool {
i++
return true
})
m.Iterator(func(k int, v interface{}) bool {
j++
return false
})
t.Assert(i, "2")
t.Assert(j, 1)
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k int, v interface{}) bool {
i++
return true
})
m.Iterator(func(k int, v interface{}) bool {
j++
return false
})
gtest.Assert(i, "2")
gtest.Assert(j, 1)
}
func Test_IntAnyMap_Lock(t *testing.T) {
expect := map[int]interface{}{1: 1, 2: "2"}
m := gmap.NewIntAnyMapFrom(expect)
m.LockFunc(func(m map[int]interface{}) {
gtest.Assert(m, expect)
})
m.RLockFunc(func(m map[int]interface{}) {
gtest.Assert(m, expect)
gtest.C(t, func(t *gtest.T) {
expect := map[int]interface{}{1: 1, 2: "2"}
m := gmap.NewIntAnyMapFrom(expect)
m.LockFunc(func(m map[int]interface{}) {
t.Assert(m, expect)
})
m.RLockFunc(func(m map[int]interface{}) {
t.Assert(m, expect)
})
})
}
func Test_IntAnyMap_Clone(t *testing.T) {
//clone 方法是深克隆
m := gmap.NewIntAnyMapFrom(map[int]interface{}{1: 1, 2: "2"})
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gmap.NewIntAnyMapFrom(map[int]interface{}{1: 1, 2: "2"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
gtest.AssertIN(1, m_clone.Keys())
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
t.AssertIN(1, m_clone.Keys())
m_clone.Remove(2)
//修改clone map,原 map 不影响
gtest.AssertIN(2, m.Keys())
m_clone.Remove(2)
//修改clone map,原 map 不影响
t.AssertIN(2, m.Keys())
})
}
func Test_IntAnyMap_Merge(t *testing.T) {
m1 := gmap.NewIntAnyMap()
m2 := gmap.NewIntAnyMap()
m1.Set(1, 1)
m2.Set(2, "2")
m1.Merge(m2)
gtest.Assert(m1.Map(), map[int]interface{}{1: 1, 2: "2"})
gtest.C(t, func(t *gtest.T) {
m1 := gmap.NewIntAnyMap()
m2 := gmap.NewIntAnyMap()
m1.Set(1, 1)
m2.Set(2, "2")
m1.Merge(m2)
t.Assert(m1.Map(), map[int]interface{}{1: 1, 2: "2"})
})
}
func Test_IntAnyMap_Map(t *testing.T) {
m := gmap.NewIntAnyMap()
m.Set(1, 0)
m.Set(2, 2)
gtest.Assert(m.Get(1), 0)
gtest.Assert(m.Get(2), 2)
data := m.Map()
gtest.Assert(data[1], 0)
gtest.Assert(data[2], 2)
data[3] = 3
gtest.Assert(m.Get(3), 3)
m.Set(4, 4)
gtest.Assert(data[4], 4)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntAnyMap()
m.Set(1, 0)
m.Set(2, 2)
t.Assert(m.Get(1), 0)
t.Assert(m.Get(2), 2)
data := m.Map()
t.Assert(data[1], 0)
t.Assert(data[2], 2)
data[3] = 3
t.Assert(m.Get(3), 3)
m.Set(4, 4)
t.Assert(data[4], 4)
})
}
func Test_IntAnyMap_MapCopy(t *testing.T) {
m := gmap.NewIntAnyMap()
m.Set(1, 0)
m.Set(2, 2)
gtest.Assert(m.Get(1), 0)
gtest.Assert(m.Get(2), 2)
data := m.MapCopy()
gtest.Assert(data[1], 0)
gtest.Assert(data[2], 2)
data[3] = 3
gtest.Assert(m.Get(3), nil)
m.Set(4, 4)
gtest.Assert(data[4], nil)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntAnyMap()
m.Set(1, 0)
m.Set(2, 2)
t.Assert(m.Get(1), 0)
t.Assert(m.Get(2), 2)
data := m.MapCopy()
t.Assert(data[1], 0)
t.Assert(data[2], 2)
data[3] = 3
t.Assert(m.Get(3), nil)
m.Set(4, 4)
t.Assert(data[4], nil)
})
}
func Test_IntAnyMap_FilterEmpty(t *testing.T) {
m := gmap.NewIntAnyMap()
m.Set(1, 0)
m.Set(2, 2)
gtest.Assert(m.Size(), 2)
gtest.Assert(m.Get(1), 0)
gtest.Assert(m.Get(2), 2)
m.FilterEmpty()
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get(2), 2)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntAnyMap()
m.Set(1, 0)
m.Set(2, 2)
t.Assert(m.Size(), 2)
t.Assert(m.Get(1), 0)
t.Assert(m.Get(2), 2)
m.FilterEmpty()
t.Assert(m.Size(), 1)
t.Assert(m.Get(2), 2)
})
}
func Test_IntAnyMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapIntAny{
1: "v1",
2: "v2",
@ -186,111 +203,111 @@ func Test_IntAnyMap_Json(t *testing.T) {
m1 := gmap.NewIntAnyMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapIntAny{
1: "v1",
2: "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
m := gmap.NewIntAnyMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get(1), data[1])
gtest.Assert(m.Get(2), data[2])
t.Assert(err, nil)
t.Assert(m.Get(1), data[1])
t.Assert(m.Get(2), data[2])
})
}
func Test_IntAnyMap_Pop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntAnyMapFrom(g.MapIntAny{
1: "v1",
2: "v2",
})
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
k1, v1 := m.Pop()
gtest.AssertIN(k1, g.Slice{1, 2})
gtest.AssertIN(v1, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 1)
t.AssertIN(k1, g.Slice{1, 2})
t.AssertIN(v1, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 1)
k2, v2 := m.Pop()
gtest.AssertIN(k2, g.Slice{1, 2})
gtest.AssertIN(v2, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 0)
t.AssertIN(k2, g.Slice{1, 2})
t.AssertIN(v2, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 0)
gtest.AssertNE(k1, k2)
gtest.AssertNE(v1, v2)
t.AssertNE(k1, k2)
t.AssertNE(v1, v2)
})
}
func Test_IntAnyMap_Pops(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntAnyMapFrom(g.MapIntAny{
1: "v1",
2: "v2",
3: "v3",
})
gtest.Assert(m.Size(), 3)
t.Assert(m.Size(), 3)
kArray := garray.New()
vArray := garray.New()
for k, v := range m.Pops(1) {
gtest.AssertIN(k, g.Slice{1, 2, 3})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{1, 2, 3})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
for k, v := range m.Pops(2) {
gtest.AssertIN(k, g.Slice{1, 2, 3})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{1, 2, 3})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 0)
t.Assert(m.Size(), 0)
gtest.Assert(kArray.Unique().Len(), 3)
gtest.Assert(vArray.Unique().Len(), 3)
t.Assert(kArray.Unique().Len(), 3)
t.Assert(vArray.Unique().Len(), 3)
})
}
func TestIntAnyMap_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Map *gmap.IntAnyMap
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"1":"v1","2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "v1")
gtest.Assert(t.Map.Get(2), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get(1), "v1")
t.Assert(v.Map.Get(2), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.MapIntAny{
1: "v1",
2: "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "v1")
gtest.Assert(t.Map.Get(2), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get(1), "v1")
t.Assert(v.Map.Get(2), "v2")
})
}

View File

@ -24,164 +24,180 @@ func intIntCallBack(int, int) bool {
return true
}
func Test_IntIntMap_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntIntMap()
m.Set(1, 1)
gtest.Assert(m.Get(1), 1)
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get(1), 1)
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet(2, 2), 2)
gtest.Assert(m.SetIfNotExist(2, 2), false)
t.Assert(m.GetOrSet(2, 2), 2)
t.Assert(m.SetIfNotExist(2, 2), false)
gtest.Assert(m.SetIfNotExist(3, 3), true)
t.Assert(m.SetIfNotExist(3, 3), true)
gtest.Assert(m.Remove(2), 2)
gtest.Assert(m.Contains(2), false)
t.Assert(m.Remove(2), 2)
t.Assert(m.Contains(2), false)
gtest.AssertIN(3, m.Keys())
gtest.AssertIN(1, m.Keys())
gtest.AssertIN(3, m.Values())
gtest.AssertIN(1, m.Values())
t.AssertIN(3, m.Keys())
t.AssertIN(1, m.Keys())
t.AssertIN(3, m.Values())
t.AssertIN(1, m.Values())
m.Flip()
gtest.Assert(m.Map(), map[int]int{1: 1, 3: 3})
t.Assert(m.Map(), map[int]int{1: 1, 3: 3})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gmap.NewIntIntMapFrom(map[int]int{1: 1, 2: 2})
gtest.Assert(m2.Map(), map[int]int{1: 1, 2: 2})
t.Assert(m2.Map(), map[int]int{1: 1, 2: 2})
})
}
func Test_IntIntMap_Set_Fun(t *testing.T) {
m := gmap.NewIntIntMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntIntMap()
m.GetOrSetFunc(1, getInt)
m.GetOrSetFuncLock(2, getInt)
gtest.Assert(m.Get(1), 123)
gtest.Assert(m.Get(2), 123)
gtest.Assert(m.SetIfNotExistFunc(1, getInt), false)
gtest.Assert(m.SetIfNotExistFunc(3, getInt), true)
gtest.Assert(m.SetIfNotExistFuncLock(2, getInt), false)
gtest.Assert(m.SetIfNotExistFuncLock(4, getInt), true)
m.GetOrSetFunc(1, getInt)
m.GetOrSetFuncLock(2, getInt)
t.Assert(m.Get(1), 123)
t.Assert(m.Get(2), 123)
t.Assert(m.SetIfNotExistFunc(1, getInt), false)
t.Assert(m.SetIfNotExistFunc(3, getInt), true)
t.Assert(m.SetIfNotExistFuncLock(2, getInt), false)
t.Assert(m.SetIfNotExistFuncLock(4, getInt), true)
})
}
func Test_IntIntMap_Batch(t *testing.T) {
m := gmap.NewIntIntMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntIntMap()
m.Sets(map[int]int{1: 1, 2: 2, 3: 3})
m.Iterator(intIntCallBack)
gtest.Assert(m.Map(), map[int]int{1: 1, 2: 2, 3: 3})
m.Removes([]int{1, 2})
gtest.Assert(m.Map(), map[int]int{3: 3})
m.Sets(map[int]int{1: 1, 2: 2, 3: 3})
m.Iterator(intIntCallBack)
t.Assert(m.Map(), map[int]int{1: 1, 2: 2, 3: 3})
m.Removes([]int{1, 2})
t.Assert(m.Map(), map[int]int{3: 3})
})
}
func Test_IntIntMap_Iterator(t *testing.T) {
expect := map[int]int{1: 1, 2: 2}
m := gmap.NewIntIntMapFrom(expect)
m.Iterator(func(k int, v int) bool {
gtest.Assert(expect[k], v)
return true
gtest.C(t, func(t *gtest.T) {
expect := map[int]int{1: 1, 2: 2}
m := gmap.NewIntIntMapFrom(expect)
m.Iterator(func(k int, v int) bool {
t.Assert(expect[k], v)
return true
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k int, v int) bool {
i++
return true
})
m.Iterator(func(k int, v int) bool {
j++
return false
})
t.Assert(i, 2)
t.Assert(j, 1)
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k int, v int) bool {
i++
return true
})
m.Iterator(func(k int, v int) bool {
j++
return false
})
gtest.Assert(i, 2)
gtest.Assert(j, 1)
}
func Test_IntIntMap_Lock(t *testing.T) {
expect := map[int]int{1: 1, 2: 2}
m := gmap.NewIntIntMapFrom(expect)
m.LockFunc(func(m map[int]int) {
gtest.Assert(m, expect)
gtest.C(t, func(t *gtest.T) {
expect := map[int]int{1: 1, 2: 2}
m := gmap.NewIntIntMapFrom(expect)
m.LockFunc(func(m map[int]int) {
t.Assert(m, expect)
})
m.RLockFunc(func(m map[int]int) {
t.Assert(m, expect)
})
})
m.RLockFunc(func(m map[int]int) {
gtest.Assert(m, expect)
})
}
func Test_IntIntMap_Clone(t *testing.T) {
//clone 方法是深克隆
m := gmap.NewIntIntMapFrom(map[int]int{1: 1, 2: 2})
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gmap.NewIntIntMapFrom(map[int]int{1: 1, 2: 2})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
gtest.AssertIN(1, m_clone.Keys())
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
t.AssertIN(1, m_clone.Keys())
m_clone.Remove(2)
//修改clone map,原 map 不影响
gtest.AssertIN(2, m.Keys())
m_clone.Remove(2)
//修改clone map,原 map 不影响
t.AssertIN(2, m.Keys())
})
}
func Test_IntIntMap_Merge(t *testing.T) {
m1 := gmap.NewIntIntMap()
m2 := gmap.NewIntIntMap()
m1.Set(1, 1)
m2.Set(2, 2)
m1.Merge(m2)
gtest.Assert(m1.Map(), map[int]int{1: 1, 2: 2})
gtest.C(t, func(t *gtest.T) {
m1 := gmap.NewIntIntMap()
m2 := gmap.NewIntIntMap()
m1.Set(1, 1)
m2.Set(2, 2)
m1.Merge(m2)
t.Assert(m1.Map(), map[int]int{1: 1, 2: 2})
})
}
func Test_IntIntMap_Map(t *testing.T) {
m := gmap.NewIntIntMap()
m.Set(1, 0)
m.Set(2, 2)
gtest.Assert(m.Get(1), 0)
gtest.Assert(m.Get(2), 2)
data := m.Map()
gtest.Assert(data[1], 0)
gtest.Assert(data[2], 2)
data[3] = 3
gtest.Assert(m.Get(3), 3)
m.Set(4, 4)
gtest.Assert(data[4], 4)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntIntMap()
m.Set(1, 0)
m.Set(2, 2)
t.Assert(m.Get(1), 0)
t.Assert(m.Get(2), 2)
data := m.Map()
t.Assert(data[1], 0)
t.Assert(data[2], 2)
data[3] = 3
t.Assert(m.Get(3), 3)
m.Set(4, 4)
t.Assert(data[4], 4)
})
}
func Test_IntIntMap_MapCopy(t *testing.T) {
m := gmap.NewIntIntMap()
m.Set(1, 0)
m.Set(2, 2)
gtest.Assert(m.Get(1), 0)
gtest.Assert(m.Get(2), 2)
data := m.MapCopy()
gtest.Assert(data[1], 0)
gtest.Assert(data[2], 2)
data[3] = 3
gtest.Assert(m.Get(3), 0)
m.Set(4, 4)
gtest.Assert(data[4], 0)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntIntMap()
m.Set(1, 0)
m.Set(2, 2)
t.Assert(m.Get(1), 0)
t.Assert(m.Get(2), 2)
data := m.MapCopy()
t.Assert(data[1], 0)
t.Assert(data[2], 2)
data[3] = 3
t.Assert(m.Get(3), 0)
m.Set(4, 4)
t.Assert(data[4], 0)
})
}
func Test_IntIntMap_FilterEmpty(t *testing.T) {
m := gmap.NewIntIntMap()
m.Set(1, 0)
m.Set(2, 2)
gtest.Assert(m.Size(), 2)
gtest.Assert(m.Get(1), 0)
gtest.Assert(m.Get(2), 2)
m.FilterEmpty()
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get(2), 2)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntIntMap()
m.Set(1, 0)
m.Set(2, 2)
t.Assert(m.Size(), 2)
t.Assert(m.Get(1), 0)
t.Assert(m.Get(2), 2)
m.FilterEmpty()
t.Assert(m.Size(), 1)
t.Assert(m.Get(2), 2)
})
}
func Test_IntIntMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapIntInt{
1: 10,
2: 20,
@ -189,111 +205,111 @@ func Test_IntIntMap_Json(t *testing.T) {
m1 := gmap.NewIntIntMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapIntInt{
1: 10,
2: 20,
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
m := gmap.NewIntIntMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get(1), data[1])
gtest.Assert(m.Get(2), data[2])
t.Assert(err, nil)
t.Assert(m.Get(1), data[1])
t.Assert(m.Get(2), data[2])
})
}
func Test_IntIntMap_Pop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntIntMapFrom(g.MapIntInt{
1: 11,
2: 22,
})
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
k1, v1 := m.Pop()
gtest.AssertIN(k1, g.Slice{1, 2})
gtest.AssertIN(v1, g.Slice{11, 22})
gtest.Assert(m.Size(), 1)
t.AssertIN(k1, g.Slice{1, 2})
t.AssertIN(v1, g.Slice{11, 22})
t.Assert(m.Size(), 1)
k2, v2 := m.Pop()
gtest.AssertIN(k2, g.Slice{1, 2})
gtest.AssertIN(v2, g.Slice{11, 22})
gtest.Assert(m.Size(), 0)
t.AssertIN(k2, g.Slice{1, 2})
t.AssertIN(v2, g.Slice{11, 22})
t.Assert(m.Size(), 0)
gtest.AssertNE(k1, k2)
gtest.AssertNE(v1, v2)
t.AssertNE(k1, k2)
t.AssertNE(v1, v2)
})
}
func Test_IntIntMap_Pops(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntIntMapFrom(g.MapIntInt{
1: 11,
2: 22,
3: 33,
})
gtest.Assert(m.Size(), 3)
t.Assert(m.Size(), 3)
kArray := garray.New()
vArray := garray.New()
for k, v := range m.Pops(1) {
gtest.AssertIN(k, g.Slice{1, 2, 3})
gtest.AssertIN(v, g.Slice{11, 22, 33})
t.AssertIN(k, g.Slice{1, 2, 3})
t.AssertIN(v, g.Slice{11, 22, 33})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
for k, v := range m.Pops(2) {
gtest.AssertIN(k, g.Slice{1, 2, 3})
gtest.AssertIN(v, g.Slice{11, 22, 33})
t.AssertIN(k, g.Slice{1, 2, 3})
t.AssertIN(v, g.Slice{11, 22, 33})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 0)
t.Assert(m.Size(), 0)
gtest.Assert(kArray.Unique().Len(), 3)
gtest.Assert(vArray.Unique().Len(), 3)
t.Assert(kArray.Unique().Len(), 3)
t.Assert(vArray.Unique().Len(), 3)
})
}
func TestIntIntMap_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Map *gmap.IntIntMap
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"1":1,"2":2}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "1")
gtest.Assert(t.Map.Get(2), "2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get(1), "1")
t.Assert(v.Map.Get(2), "2")
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.MapIntAny{
1: 1,
2: 2,
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "1")
gtest.Assert(t.Map.Get(2), "2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get(1), "1")
t.Assert(v.Map.Get(2), "2")
})
}

View File

@ -24,165 +24,179 @@ func intStrCallBack(int, string) bool {
return true
}
func Test_IntStrMap_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntStrMap()
m.Set(1, "a")
gtest.Assert(m.Get(1), "a")
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get(1), "a")
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet(2, "b"), "b")
gtest.Assert(m.SetIfNotExist(2, "b"), false)
t.Assert(m.GetOrSet(2, "b"), "b")
t.Assert(m.SetIfNotExist(2, "b"), false)
gtest.Assert(m.SetIfNotExist(3, "c"), true)
t.Assert(m.SetIfNotExist(3, "c"), true)
gtest.Assert(m.Remove(2), "b")
gtest.Assert(m.Contains(2), false)
t.Assert(m.Remove(2), "b")
t.Assert(m.Contains(2), false)
gtest.AssertIN(3, m.Keys())
gtest.AssertIN(1, m.Keys())
gtest.AssertIN("a", m.Values())
gtest.AssertIN("c", m.Values())
t.AssertIN(3, m.Keys())
t.AssertIN(1, m.Keys())
t.AssertIN("a", m.Values())
t.AssertIN("c", m.Values())
//反转之后不成为以下 map,flip 操作只是翻转原 map
//gtest.Assert(m.Map(), map[string]int{"a": 1, "c": 3})
//t.Assert(m.Map(), map[string]int{"a": 1, "c": 3})
m_f := gmap.NewIntStrMap()
m_f.Set(1, "2")
m_f.Flip()
gtest.Assert(m_f.Map(), map[int]string{2: "1"})
t.Assert(m_f.Map(), map[int]string{2: "1"})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gmap.NewIntStrMapFrom(map[int]string{1: "a", 2: "b"})
gtest.Assert(m2.Map(), map[int]string{1: "a", 2: "b"})
t.Assert(m2.Map(), map[int]string{1: "a", 2: "b"})
})
}
func Test_IntStrMap_Set_Fun(t *testing.T) {
m := gmap.NewIntStrMap()
m.GetOrSetFunc(1, getStr)
m.GetOrSetFuncLock(2, getStr)
gtest.Assert(m.Get(1), "z")
gtest.Assert(m.Get(2), "z")
gtest.Assert(m.SetIfNotExistFunc(1, getStr), false)
gtest.Assert(m.SetIfNotExistFunc(3, getStr), true)
gtest.Assert(m.SetIfNotExistFuncLock(2, getStr), false)
gtest.Assert(m.SetIfNotExistFuncLock(4, getStr), true)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntStrMap()
m.GetOrSetFunc(1, getStr)
m.GetOrSetFuncLock(2, getStr)
t.Assert(m.Get(1), "z")
t.Assert(m.Get(2), "z")
t.Assert(m.SetIfNotExistFunc(1, getStr), false)
t.Assert(m.SetIfNotExistFunc(3, getStr), true)
t.Assert(m.SetIfNotExistFuncLock(2, getStr), false)
t.Assert(m.SetIfNotExistFuncLock(4, getStr), true)
})
}
func Test_IntStrMap_Batch(t *testing.T) {
m := gmap.NewIntStrMap()
m.Sets(map[int]string{1: "a", 2: "b", 3: "c"})
gtest.Assert(m.Map(), map[int]string{1: "a", 2: "b", 3: "c"})
m.Removes([]int{1, 2})
gtest.Assert(m.Map(), map[int]interface{}{3: "c"})
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntStrMap()
m.Sets(map[int]string{1: "a", 2: "b", 3: "c"})
t.Assert(m.Map(), map[int]string{1: "a", 2: "b", 3: "c"})
m.Removes([]int{1, 2})
t.Assert(m.Map(), map[int]interface{}{3: "c"})
})
}
func Test_IntStrMap_Iterator(t *testing.T) {
expect := map[int]string{1: "a", 2: "b"}
m := gmap.NewIntStrMapFrom(expect)
m.Iterator(func(k int, v string) bool {
gtest.Assert(expect[k], v)
return true
gtest.C(t, func(t *gtest.T) {
expect := map[int]string{1: "a", 2: "b"}
m := gmap.NewIntStrMapFrom(expect)
m.Iterator(func(k int, v string) bool {
t.Assert(expect[k], v)
return true
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k int, v string) bool {
i++
return true
})
m.Iterator(func(k int, v string) bool {
j++
return false
})
t.Assert(i, 2)
t.Assert(j, 1)
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k int, v string) bool {
i++
return true
})
m.Iterator(func(k int, v string) bool {
j++
return false
})
gtest.Assert(i, 2)
gtest.Assert(j, 1)
}
func Test_IntStrMap_Lock(t *testing.T) {
expect := map[int]string{1: "a", 2: "b", 3: "c"}
m := gmap.NewIntStrMapFrom(expect)
m.LockFunc(func(m map[int]string) {
gtest.Assert(m, expect)
gtest.C(t, func(t *gtest.T) {
expect := map[int]string{1: "a", 2: "b", 3: "c"}
m := gmap.NewIntStrMapFrom(expect)
m.LockFunc(func(m map[int]string) {
t.Assert(m, expect)
})
m.RLockFunc(func(m map[int]string) {
t.Assert(m, expect)
})
})
m.RLockFunc(func(m map[int]string) {
gtest.Assert(m, expect)
})
}
func Test_IntStrMap_Clone(t *testing.T) {
//clone 方法是深克隆
m := gmap.NewIntStrMapFrom(map[int]string{1: "a", 2: "b", 3: "c"})
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gmap.NewIntStrMapFrom(map[int]string{1: "a", 2: "b", 3: "c"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
gtest.AssertIN(1, m_clone.Keys())
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
t.AssertIN(1, m_clone.Keys())
m_clone.Remove(2)
//修改clone map,原 map 不影响
gtest.AssertIN(2, m.Keys())
m_clone.Remove(2)
//修改clone map,原 map 不影响
t.AssertIN(2, m.Keys())
})
}
func Test_IntStrMap_Merge(t *testing.T) {
m1 := gmap.NewIntStrMap()
m2 := gmap.NewIntStrMap()
m1.Set(1, "a")
m2.Set(2, "b")
m1.Merge(m2)
gtest.Assert(m1.Map(), map[int]string{1: "a", 2: "b"})
gtest.C(t, func(t *gtest.T) {
m1 := gmap.NewIntStrMap()
m2 := gmap.NewIntStrMap()
m1.Set(1, "a")
m2.Set(2, "b")
m1.Merge(m2)
t.Assert(m1.Map(), map[int]string{1: "a", 2: "b"})
})
}
func Test_IntStrMap_Map(t *testing.T) {
m := gmap.NewIntStrMap()
m.Set(1, "0")
m.Set(2, "2")
gtest.Assert(m.Get(1), "0")
gtest.Assert(m.Get(2), "2")
data := m.Map()
gtest.Assert(data[1], "0")
gtest.Assert(data[2], "2")
data[3] = "3"
gtest.Assert(m.Get(3), "3")
m.Set(4, "4")
gtest.Assert(data[4], "4")
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntStrMap()
m.Set(1, "0")
m.Set(2, "2")
t.Assert(m.Get(1), "0")
t.Assert(m.Get(2), "2")
data := m.Map()
t.Assert(data[1], "0")
t.Assert(data[2], "2")
data[3] = "3"
t.Assert(m.Get(3), "3")
m.Set(4, "4")
t.Assert(data[4], "4")
})
}
func Test_IntStrMap_MapCopy(t *testing.T) {
m := gmap.NewIntStrMap()
m.Set(1, "0")
m.Set(2, "2")
gtest.Assert(m.Get(1), "0")
gtest.Assert(m.Get(2), "2")
data := m.MapCopy()
gtest.Assert(data[1], "0")
gtest.Assert(data[2], "2")
data[3] = "3"
gtest.Assert(m.Get(3), "")
m.Set(4, "4")
gtest.Assert(data[4], "")
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntStrMap()
m.Set(1, "0")
m.Set(2, "2")
t.Assert(m.Get(1), "0")
t.Assert(m.Get(2), "2")
data := m.MapCopy()
t.Assert(data[1], "0")
t.Assert(data[2], "2")
data[3] = "3"
t.Assert(m.Get(3), "")
m.Set(4, "4")
t.Assert(data[4], "")
})
}
func Test_IntStrMap_FilterEmpty(t *testing.T) {
m := gmap.NewIntStrMap()
m.Set(1, "")
m.Set(2, "2")
gtest.Assert(m.Size(), 2)
gtest.Assert(m.Get(2), "2")
m.FilterEmpty()
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get(2), "2")
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntStrMap()
m.Set(1, "")
m.Set(2, "2")
t.Assert(m.Size(), 2)
t.Assert(m.Get(2), "2")
m.FilterEmpty()
t.Assert(m.Size(), 1)
t.Assert(m.Get(2), "2")
})
}
func Test_IntStrMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapIntStr{
1: "v1",
2: "v2",
@ -190,111 +204,111 @@ func Test_IntStrMap_Json(t *testing.T) {
m1 := gmap.NewIntStrMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapIntStr{
1: "v1",
2: "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
m := gmap.NewIntStrMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get(1), data[1])
gtest.Assert(m.Get(2), data[2])
t.Assert(err, nil)
t.Assert(m.Get(1), data[1])
t.Assert(m.Get(2), data[2])
})
}
func Test_IntStrMap_Pop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntStrMapFrom(g.MapIntStr{
1: "v1",
2: "v2",
})
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
k1, v1 := m.Pop()
gtest.AssertIN(k1, g.Slice{1, 2})
gtest.AssertIN(v1, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 1)
t.AssertIN(k1, g.Slice{1, 2})
t.AssertIN(v1, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 1)
k2, v2 := m.Pop()
gtest.AssertIN(k2, g.Slice{1, 2})
gtest.AssertIN(v2, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 0)
t.AssertIN(k2, g.Slice{1, 2})
t.AssertIN(v2, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 0)
gtest.AssertNE(k1, k2)
gtest.AssertNE(v1, v2)
t.AssertNE(k1, k2)
t.AssertNE(v1, v2)
})
}
func Test_IntStrMap_Pops(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewIntStrMapFrom(g.MapIntStr{
1: "v1",
2: "v2",
3: "v3",
})
gtest.Assert(m.Size(), 3)
t.Assert(m.Size(), 3)
kArray := garray.New()
vArray := garray.New()
for k, v := range m.Pops(1) {
gtest.AssertIN(k, g.Slice{1, 2, 3})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{1, 2, 3})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
for k, v := range m.Pops(2) {
gtest.AssertIN(k, g.Slice{1, 2, 3})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{1, 2, 3})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 0)
t.Assert(m.Size(), 0)
gtest.Assert(kArray.Unique().Len(), 3)
gtest.Assert(vArray.Unique().Len(), 3)
t.Assert(kArray.Unique().Len(), 3)
t.Assert(vArray.Unique().Len(), 3)
})
}
func TestIntStrMap_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Map *gmap.IntStrMap
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"1":"v1","2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "v1")
gtest.Assert(t.Map.Get(2), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get(1), "v1")
t.Assert(v.Map.Get(2), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.MapIntAny{
1: "v1",
2: "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "v1")
gtest.Assert(t.Map.Get(2), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get(1), "v1")
t.Assert(v.Map.Get(2), "v2")
})
}

View File

@ -18,125 +18,139 @@ import (
)
func Test_ListMap_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewListMap()
m.Set("key1", "val1")
gtest.Assert(m.Keys(), []interface{}{"key1"})
t.Assert(m.Keys(), []interface{}{"key1"})
gtest.Assert(m.Get("key1"), "val1")
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get("key1"), "val1")
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet("key2", "val2"), "val2")
gtest.Assert(m.SetIfNotExist("key2", "val2"), false)
t.Assert(m.GetOrSet("key2", "val2"), "val2")
t.Assert(m.SetIfNotExist("key2", "val2"), false)
gtest.Assert(m.SetIfNotExist("key3", "val3"), true)
gtest.Assert(m.Remove("key2"), "val2")
gtest.Assert(m.Contains("key2"), false)
t.Assert(m.SetIfNotExist("key3", "val3"), true)
t.Assert(m.Remove("key2"), "val2")
t.Assert(m.Contains("key2"), false)
gtest.AssertIN("key3", m.Keys())
gtest.AssertIN("key1", m.Keys())
gtest.AssertIN("val3", m.Values())
gtest.AssertIN("val1", m.Values())
t.AssertIN("key3", m.Keys())
t.AssertIN("key1", m.Keys())
t.AssertIN("val3", m.Values())
t.AssertIN("val1", m.Values())
m.Flip()
gtest.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val1": "key1"})
t.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val1": "key1"})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gmap.NewListMapFrom(map[interface{}]interface{}{1: 1, "key1": "val1"})
gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
t.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
})
}
func Test_ListMap_Set_Fun(t *testing.T) {
m := gmap.NewListMap()
m.GetOrSetFunc("fun", getValue)
m.GetOrSetFuncLock("funlock", getValue)
gtest.Assert(m.Get("funlock"), 3)
gtest.Assert(m.Get("fun"), 3)
m.GetOrSetFunc("fun", getValue)
gtest.Assert(m.SetIfNotExistFunc("fun", getValue), false)
gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewListMap()
m.GetOrSetFunc("fun", getValue)
m.GetOrSetFuncLock("funlock", getValue)
t.Assert(m.Get("funlock"), 3)
t.Assert(m.Get("fun"), 3)
m.GetOrSetFunc("fun", getValue)
t.Assert(m.SetIfNotExistFunc("fun", getValue), false)
t.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
})
}
func Test_ListMap_Batch(t *testing.T) {
m := gmap.NewListMap()
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
gtest.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
gtest.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
gtest.C(t, func(t *gtest.T) {
m := gmap.NewListMap()
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
t.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
t.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
})
}
func Test_ListMap_Iterator(t *testing.T) {
expect := map[interface{}]interface{}{1: 1, "key1": "val1"}
gtest.C(t, func(t *gtest.T) {
expect := map[interface{}]interface{}{1: 1, "key1": "val1"}
m := gmap.NewListMapFrom(expect)
m.Iterator(func(k interface{}, v interface{}) bool {
gtest.Assert(expect[k], v)
return true
m := gmap.NewListMapFrom(expect)
m.Iterator(func(k interface{}, v interface{}) bool {
t.Assert(expect[k], v)
return true
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k interface{}, v interface{}) bool {
i++
return true
})
m.Iterator(func(k interface{}, v interface{}) bool {
j++
return false
})
t.Assert(i, 2)
t.Assert(j, 1)
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k interface{}, v interface{}) bool {
i++
return true
})
m.Iterator(func(k interface{}, v interface{}) bool {
j++
return false
})
gtest.Assert(i, 2)
gtest.Assert(j, 1)
}
func Test_ListMap_Clone(t *testing.T) {
//clone 方法是深克隆
m := gmap.NewListMapFrom(map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
gtest.AssertIN(1, m_clone.Keys())
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gmap.NewListMapFrom(map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
t.AssertIN(1, m_clone.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
gtest.AssertIN("key1", m.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
t.AssertIN("key1", m.Keys())
})
}
func Test_ListMap_Basic_Merge(t *testing.T) {
m1 := gmap.NewListMap()
m2 := gmap.NewListMap()
m1.Set("key1", "val1")
m2.Set("key2", "val2")
m1.Merge(m2)
gtest.Assert(m1.Map(), map[interface{}]interface{}{"key1": "val1", "key2": "val2"})
gtest.C(t, func(t *gtest.T) {
m1 := gmap.NewListMap()
m2 := gmap.NewListMap()
m1.Set("key1", "val1")
m2.Set("key2", "val2")
m1.Merge(m2)
t.Assert(m1.Map(), map[interface{}]interface{}{"key1": "val1", "key2": "val2"})
})
}
func Test_ListMap_Order(t *testing.T) {
m := gmap.NewListMap()
m.Set("k1", "v1")
m.Set("k2", "v2")
m.Set("k3", "v3")
gtest.Assert(m.Keys(), g.Slice{"k1", "k2", "k3"})
gtest.Assert(m.Values(), g.Slice{"v1", "v2", "v3"})
gtest.C(t, func(t *gtest.T) {
m := gmap.NewListMap()
m.Set("k1", "v1")
m.Set("k2", "v2")
m.Set("k3", "v3")
t.Assert(m.Keys(), g.Slice{"k1", "k2", "k3"})
t.Assert(m.Values(), g.Slice{"v1", "v2", "v3"})
})
}
func Test_ListMap_FilterEmpty(t *testing.T) {
m := gmap.NewListMap()
m.Set(1, "")
m.Set(2, "2")
gtest.Assert(m.Size(), 2)
gtest.Assert(m.Get(2), "2")
m.FilterEmpty()
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get(2), "2")
gtest.C(t, func(t *gtest.T) {
m := gmap.NewListMap()
m.Set(1, "")
m.Set(2, "2")
t.Assert(m.Size(), 2)
t.Assert(m.Get(2), "2")
m.FilterEmpty()
t.Assert(m.Size(), 1)
t.Assert(m.Get(2), "2")
})
}
func Test_ListMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
@ -144,126 +158,126 @@ func Test_ListMap_Json(t *testing.T) {
m1 := gmap.NewListMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(gconv.Map(data))
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
t.Assert(err, nil)
m := gmap.NewListMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
t.Assert(err, nil)
var m gmap.ListMap
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
}
func Test_ListMap_Pop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewListMapFrom(g.MapAnyAny{
"k1": "v1",
"k2": "v2",
})
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
k1, v1 := m.Pop()
gtest.AssertIN(k1, g.Slice{"k1", "k2"})
gtest.AssertIN(v1, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 1)
t.AssertIN(k1, g.Slice{"k1", "k2"})
t.AssertIN(v1, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 1)
k2, v2 := m.Pop()
gtest.AssertIN(k2, g.Slice{"k1", "k2"})
gtest.AssertIN(v2, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 0)
t.AssertIN(k2, g.Slice{"k1", "k2"})
t.AssertIN(v2, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 0)
gtest.AssertNE(k1, k2)
gtest.AssertNE(v1, v2)
t.AssertNE(k1, k2)
t.AssertNE(v1, v2)
})
}
func Test_ListMap_Pops(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewListMapFrom(g.MapAnyAny{
"k1": "v1",
"k2": "v2",
"k3": "v3",
})
gtest.Assert(m.Size(), 3)
t.Assert(m.Size(), 3)
kArray := garray.New()
vArray := garray.New()
for k, v := range m.Pops(1) {
gtest.AssertIN(k, g.Slice{"k1", "k2", "k3"})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
for k, v := range m.Pops(2) {
gtest.AssertIN(k, g.Slice{"k1", "k2", "k3"})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 0)
t.Assert(m.Size(), 0)
gtest.Assert(kArray.Unique().Len(), 3)
gtest.Assert(vArray.Unique().Len(), 3)
t.Assert(kArray.Unique().Len(), 3)
t.Assert(vArray.Unique().Len(), 3)
})
}
func TestListMap_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Map *gmap.ListMap
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"1":"v1","2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("1"), "v1")
gtest.Assert(t.Map.Get("2"), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("1"), "v1")
t.Assert(v.Map.Get("2"), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.MapIntAny{
1: "v1",
2: "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("1"), "v1")
gtest.Assert(t.Map.Get("2"), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("1"), "v1")
t.Assert(v.Map.Get("2"), "v2")
})
}

View File

@ -21,162 +21,179 @@ func stringAnyCallBack(string, interface{}) bool {
return true
}
func Test_StrAnyMap_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrAnyMap()
m.Set("a", 1)
gtest.Assert(m.Get("a"), 1)
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get("a"), 1)
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet("b", "2"), "2")
gtest.Assert(m.SetIfNotExist("b", "2"), false)
t.Assert(m.GetOrSet("b", "2"), "2")
t.Assert(m.SetIfNotExist("b", "2"), false)
gtest.Assert(m.SetIfNotExist("c", 3), true)
t.Assert(m.SetIfNotExist("c", 3), true)
gtest.Assert(m.Remove("b"), "2")
gtest.Assert(m.Contains("b"), false)
t.Assert(m.Remove("b"), "2")
t.Assert(m.Contains("b"), false)
gtest.AssertIN("c", m.Keys())
gtest.AssertIN("a", m.Keys())
gtest.AssertIN(3, m.Values())
gtest.AssertIN(1, m.Values())
t.AssertIN("c", m.Keys())
t.AssertIN("a", m.Keys())
t.AssertIN(3, m.Values())
t.AssertIN(1, m.Values())
m.Flip()
gtest.Assert(m.Map(), map[string]interface{}{"1": "a", "3": "c"})
t.Assert(m.Map(), map[string]interface{}{"1": "a", "3": "c"})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gmap.NewStrAnyMapFrom(map[string]interface{}{"a": 1, "b": "2"})
gtest.Assert(m2.Map(), map[string]interface{}{"a": 1, "b": "2"})
t.Assert(m2.Map(), map[string]interface{}{"a": 1, "b": "2"})
})
}
func Test_StrAnyMap_Set_Fun(t *testing.T) {
m := gmap.NewStrAnyMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrAnyMap()
m.GetOrSetFunc("a", getAny)
m.GetOrSetFuncLock("b", getAny)
gtest.Assert(m.Get("a"), 123)
gtest.Assert(m.Get("b"), 123)
gtest.Assert(m.SetIfNotExistFunc("a", getAny), false)
gtest.Assert(m.SetIfNotExistFunc("c", getAny), true)
gtest.Assert(m.SetIfNotExistFuncLock("b", getAny), false)
gtest.Assert(m.SetIfNotExistFuncLock("d", getAny), true)
m.GetOrSetFunc("a", getAny)
m.GetOrSetFuncLock("b", getAny)
t.Assert(m.Get("a"), 123)
t.Assert(m.Get("b"), 123)
t.Assert(m.SetIfNotExistFunc("a", getAny), false)
t.Assert(m.SetIfNotExistFunc("c", getAny), true)
t.Assert(m.SetIfNotExistFuncLock("b", getAny), false)
t.Assert(m.SetIfNotExistFuncLock("d", getAny), true)
})
}
func Test_StrAnyMap_Batch(t *testing.T) {
m := gmap.NewStrAnyMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrAnyMap()
m.Sets(map[string]interface{}{"a": 1, "b": "2", "c": 3})
gtest.Assert(m.Map(), map[string]interface{}{"a": 1, "b": "2", "c": 3})
m.Removes([]string{"a", "b"})
gtest.Assert(m.Map(), map[string]interface{}{"c": 3})
m.Sets(map[string]interface{}{"a": 1, "b": "2", "c": 3})
t.Assert(m.Map(), map[string]interface{}{"a": 1, "b": "2", "c": 3})
m.Removes([]string{"a", "b"})
t.Assert(m.Map(), map[string]interface{}{"c": 3})
})
}
func Test_StrAnyMap_Iterator(t *testing.T) {
expect := map[string]interface{}{"a": true, "b": false}
m := gmap.NewStrAnyMapFrom(expect)
m.Iterator(func(k string, v interface{}) bool {
gtest.Assert(expect[k], v)
return true
gtest.C(t, func(t *gtest.T) {
expect := map[string]interface{}{"a": true, "b": false}
m := gmap.NewStrAnyMapFrom(expect)
m.Iterator(func(k string, v interface{}) bool {
t.Assert(expect[k], v)
return true
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k string, v interface{}) bool {
i++
return true
})
m.Iterator(func(k string, v interface{}) bool {
j++
return false
})
t.Assert(i, 2)
t.Assert(j, 1)
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k string, v interface{}) bool {
i++
return true
})
m.Iterator(func(k string, v interface{}) bool {
j++
return false
})
gtest.Assert(i, 2)
gtest.Assert(j, 1)
}
func Test_StrAnyMap_Lock(t *testing.T) {
expect := map[string]interface{}{"a": true, "b": false}
gtest.C(t, func(t *gtest.T) {
expect := map[string]interface{}{"a": true, "b": false}
m := gmap.NewStrAnyMapFrom(expect)
m.LockFunc(func(m map[string]interface{}) {
gtest.Assert(m, expect)
})
m.RLockFunc(func(m map[string]interface{}) {
gtest.Assert(m, expect)
m := gmap.NewStrAnyMapFrom(expect)
m.LockFunc(func(m map[string]interface{}) {
t.Assert(m, expect)
})
m.RLockFunc(func(m map[string]interface{}) {
t.Assert(m, expect)
})
})
}
func Test_StrAnyMap_Clone(t *testing.T) {
//clone 方法是深克隆
m := gmap.NewStrAnyMapFrom(map[string]interface{}{"a": 1, "b": "2"})
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gmap.NewStrAnyMapFrom(map[string]interface{}{"a": 1, "b": "2"})
m_clone := m.Clone()
m.Remove("a")
//修改原 map,clone 后的 map 不影响
gtest.AssertIN("a", m_clone.Keys())
m_clone := m.Clone()
m.Remove("a")
//修改原 map,clone 后的 map 不影响
t.AssertIN("a", m_clone.Keys())
m_clone.Remove("b")
//修改clone map,原 map 不影响
gtest.AssertIN("b", m.Keys())
m_clone.Remove("b")
//修改clone map,原 map 不影响
t.AssertIN("b", m.Keys())
})
}
func Test_StrAnyMap_Merge(t *testing.T) {
m1 := gmap.NewStrAnyMap()
m2 := gmap.NewStrAnyMap()
m1.Set("a", 1)
m2.Set("b", "2")
m1.Merge(m2)
gtest.Assert(m1.Map(), map[string]interface{}{"a": 1, "b": "2"})
gtest.C(t, func(t *gtest.T) {
m1 := gmap.NewStrAnyMap()
m2 := gmap.NewStrAnyMap()
m1.Set("a", 1)
m2.Set("b", "2")
m1.Merge(m2)
t.Assert(m1.Map(), map[string]interface{}{"a": 1, "b": "2"})
})
}
func Test_StrAnyMap_Map(t *testing.T) {
m := gmap.NewStrAnyMap()
m.Set("1", 1)
m.Set("2", 2)
gtest.Assert(m.Get("1"), 1)
gtest.Assert(m.Get("2"), 2)
data := m.Map()
gtest.Assert(data["1"], 1)
gtest.Assert(data["2"], 2)
data["3"] = 3
gtest.Assert(m.Get("3"), 3)
m.Set("4", 4)
gtest.Assert(data["4"], 4)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrAnyMap()
m.Set("1", 1)
m.Set("2", 2)
t.Assert(m.Get("1"), 1)
t.Assert(m.Get("2"), 2)
data := m.Map()
t.Assert(data["1"], 1)
t.Assert(data["2"], 2)
data["3"] = 3
t.Assert(m.Get("3"), 3)
m.Set("4", 4)
t.Assert(data["4"], 4)
})
}
func Test_StrAnyMap_MapCopy(t *testing.T) {
m := gmap.NewStrAnyMap()
m.Set("1", 1)
m.Set("2", 2)
gtest.Assert(m.Get("1"), 1)
gtest.Assert(m.Get("2"), 2)
data := m.MapCopy()
gtest.Assert(data["1"], 1)
gtest.Assert(data["2"], 2)
data["3"] = 3
gtest.Assert(m.Get("3"), nil)
m.Set("4", 4)
gtest.Assert(data["4"], nil)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrAnyMap()
m.Set("1", 1)
m.Set("2", 2)
t.Assert(m.Get("1"), 1)
t.Assert(m.Get("2"), 2)
data := m.MapCopy()
t.Assert(data["1"], 1)
t.Assert(data["2"], 2)
data["3"] = 3
t.Assert(m.Get("3"), nil)
m.Set("4", 4)
t.Assert(data["4"], nil)
})
}
func Test_StrAnyMap_FilterEmpty(t *testing.T) {
m := gmap.NewStrAnyMap()
m.Set("1", 0)
m.Set("2", 2)
gtest.Assert(m.Size(), 2)
gtest.Assert(m.Get("1"), 0)
gtest.Assert(m.Get("2"), 2)
m.FilterEmpty()
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get("2"), 2)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrAnyMap()
m.Set("1", 0)
m.Set("2", 2)
t.Assert(m.Size(), 2)
t.Assert(m.Get("1"), 0)
t.Assert(m.Get("2"), 2)
m.FilterEmpty()
t.Assert(m.Size(), 1)
t.Assert(m.Get("2"), 2)
})
}
func Test_StrAnyMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapStrAny{
"k1": "v1",
"k2": "v2",
@ -184,125 +201,125 @@ func Test_StrAnyMap_Json(t *testing.T) {
m1 := gmap.NewStrAnyMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapStrAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
m := gmap.NewStrAnyMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapStrAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
var m gmap.StrAnyMap
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
}
func Test_StrAnyMap_Pop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrAnyMapFrom(g.MapStrAny{
"k1": "v1",
"k2": "v2",
})
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
k1, v1 := m.Pop()
gtest.AssertIN(k1, g.Slice{"k1", "k2"})
gtest.AssertIN(v1, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 1)
t.AssertIN(k1, g.Slice{"k1", "k2"})
t.AssertIN(v1, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 1)
k2, v2 := m.Pop()
gtest.AssertIN(k2, g.Slice{"k1", "k2"})
gtest.AssertIN(v2, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 0)
t.AssertIN(k2, g.Slice{"k1", "k2"})
t.AssertIN(v2, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 0)
gtest.AssertNE(k1, k2)
gtest.AssertNE(v1, v2)
t.AssertNE(k1, k2)
t.AssertNE(v1, v2)
})
}
func Test_StrAnyMap_Pops(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrAnyMapFrom(g.MapStrAny{
"k1": "v1",
"k2": "v2",
"k3": "v3",
})
gtest.Assert(m.Size(), 3)
t.Assert(m.Size(), 3)
kArray := garray.New()
vArray := garray.New()
for k, v := range m.Pops(1) {
gtest.AssertIN(k, g.Slice{"k1", "k2", "k3"})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
for k, v := range m.Pops(2) {
gtest.AssertIN(k, g.Slice{"k1", "k2", "k3"})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 0)
t.Assert(m.Size(), 0)
gtest.Assert(kArray.Unique().Len(), 3)
gtest.Assert(vArray.Unique().Len(), 3)
t.Assert(kArray.Unique().Len(), 3)
t.Assert(vArray.Unique().Len(), 3)
})
}
func TestStrAnyMap_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Map *gmap.StrAnyMap
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"k1":"v1","k2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("k1"), "v1")
t.Assert(v.Map.Get("k2"), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.Map{
"k1": "v1",
"k2": "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("k1"), "v1")
t.Assert(v.Map.Get("k2"), "v2")
})
}

View File

@ -21,165 +21,181 @@ func stringIntCallBack(string, int) bool {
return true
}
func Test_StrIntMap_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrIntMap()
m.Set("a", 1)
gtest.Assert(m.Get("a"), 1)
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get("a"), 1)
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet("b", 2), 2)
gtest.Assert(m.SetIfNotExist("b", 2), false)
t.Assert(m.GetOrSet("b", 2), 2)
t.Assert(m.SetIfNotExist("b", 2), false)
gtest.Assert(m.SetIfNotExist("c", 3), true)
t.Assert(m.SetIfNotExist("c", 3), true)
gtest.Assert(m.Remove("b"), 2)
gtest.Assert(m.Contains("b"), false)
t.Assert(m.Remove("b"), 2)
t.Assert(m.Contains("b"), false)
gtest.AssertIN("c", m.Keys())
gtest.AssertIN("a", m.Keys())
gtest.AssertIN(3, m.Values())
gtest.AssertIN(1, m.Values())
t.AssertIN("c", m.Keys())
t.AssertIN("a", m.Keys())
t.AssertIN(3, m.Values())
t.AssertIN(1, m.Values())
m_f := gmap.NewStrIntMap()
m_f.Set("1", 2)
m_f.Flip()
gtest.Assert(m_f.Map(), map[string]int{"2": 1})
t.Assert(m_f.Map(), map[string]int{"2": 1})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gmap.NewStrIntMapFrom(map[string]int{"a": 1, "b": 2})
gtest.Assert(m2.Map(), map[string]int{"a": 1, "b": 2})
t.Assert(m2.Map(), map[string]int{"a": 1, "b": 2})
})
}
func Test_StrIntMap_Set_Fun(t *testing.T) {
m := gmap.NewStrIntMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrIntMap()
m.GetOrSetFunc("a", getInt)
m.GetOrSetFuncLock("b", getInt)
gtest.Assert(m.Get("a"), 123)
gtest.Assert(m.Get("b"), 123)
gtest.Assert(m.SetIfNotExistFunc("a", getInt), false)
gtest.Assert(m.SetIfNotExistFunc("c", getInt), true)
gtest.Assert(m.SetIfNotExistFuncLock("b", getInt), false)
gtest.Assert(m.SetIfNotExistFuncLock("d", getInt), true)
m.GetOrSetFunc("a", getInt)
m.GetOrSetFuncLock("b", getInt)
t.Assert(m.Get("a"), 123)
t.Assert(m.Get("b"), 123)
t.Assert(m.SetIfNotExistFunc("a", getInt), false)
t.Assert(m.SetIfNotExistFunc("c", getInt), true)
t.Assert(m.SetIfNotExistFuncLock("b", getInt), false)
t.Assert(m.SetIfNotExistFuncLock("d", getInt), true)
})
}
func Test_StrIntMap_Batch(t *testing.T) {
m := gmap.NewStrIntMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrIntMap()
m.Sets(map[string]int{"a": 1, "b": 2, "c": 3})
gtest.Assert(m.Map(), map[string]int{"a": 1, "b": 2, "c": 3})
m.Removes([]string{"a", "b"})
gtest.Assert(m.Map(), map[string]int{"c": 3})
m.Sets(map[string]int{"a": 1, "b": 2, "c": 3})
t.Assert(m.Map(), map[string]int{"a": 1, "b": 2, "c": 3})
m.Removes([]string{"a", "b"})
t.Assert(m.Map(), map[string]int{"c": 3})
})
}
func Test_StrIntMap_Iterator(t *testing.T) {
expect := map[string]int{"a": 1, "b": 2}
m := gmap.NewStrIntMapFrom(expect)
m.Iterator(func(k string, v int) bool {
gtest.Assert(expect[k], v)
return true
gtest.C(t, func(t *gtest.T) {
expect := map[string]int{"a": 1, "b": 2}
m := gmap.NewStrIntMapFrom(expect)
m.Iterator(func(k string, v int) bool {
t.Assert(expect[k], v)
return true
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k string, v int) bool {
i++
return true
})
m.Iterator(func(k string, v int) bool {
j++
return false
})
t.Assert(i, 2)
t.Assert(j, 1)
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k string, v int) bool {
i++
return true
})
m.Iterator(func(k string, v int) bool {
j++
return false
})
gtest.Assert(i, 2)
gtest.Assert(j, 1)
}
func Test_StrIntMap_Lock(t *testing.T) {
expect := map[string]int{"a": 1, "b": 2}
gtest.C(t, func(t *gtest.T) {
expect := map[string]int{"a": 1, "b": 2}
m := gmap.NewStrIntMapFrom(expect)
m.LockFunc(func(m map[string]int) {
gtest.Assert(m, expect)
})
m.RLockFunc(func(m map[string]int) {
gtest.Assert(m, expect)
m := gmap.NewStrIntMapFrom(expect)
m.LockFunc(func(m map[string]int) {
t.Assert(m, expect)
})
m.RLockFunc(func(m map[string]int) {
t.Assert(m, expect)
})
})
}
func Test_StrIntMap_Clone(t *testing.T) {
//clone 方法是深克隆
m := gmap.NewStrIntMapFrom(map[string]int{"a": 1, "b": 2, "c": 3})
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gmap.NewStrIntMapFrom(map[string]int{"a": 1, "b": 2, "c": 3})
m_clone := m.Clone()
m.Remove("a")
//修改原 map,clone 后的 map 不影响
gtest.AssertIN("a", m_clone.Keys())
m_clone := m.Clone()
m.Remove("a")
//修改原 map,clone 后的 map 不影响
t.AssertIN("a", m_clone.Keys())
m_clone.Remove("b")
//修改clone map,原 map 不影响
gtest.AssertIN("b", m.Keys())
m_clone.Remove("b")
//修改clone map,原 map 不影响
t.AssertIN("b", m.Keys())
})
}
func Test_StrIntMap_Merge(t *testing.T) {
m1 := gmap.NewStrIntMap()
m2 := gmap.NewStrIntMap()
m1.Set("a", 1)
m2.Set("b", 2)
m1.Merge(m2)
gtest.Assert(m1.Map(), map[string]int{"a": 1, "b": 2})
gtest.C(t, func(t *gtest.T) {
m1 := gmap.NewStrIntMap()
m2 := gmap.NewStrIntMap()
m1.Set("a", 1)
m2.Set("b", 2)
m1.Merge(m2)
t.Assert(m1.Map(), map[string]int{"a": 1, "b": 2})
})
}
func Test_StrIntMap_Map(t *testing.T) {
m := gmap.NewStrIntMap()
m.Set("1", 1)
m.Set("2", 2)
gtest.Assert(m.Get("1"), 1)
gtest.Assert(m.Get("2"), 2)
data := m.Map()
gtest.Assert(data["1"], 1)
gtest.Assert(data["2"], 2)
data["3"] = 3
gtest.Assert(m.Get("3"), 3)
m.Set("4", 4)
gtest.Assert(data["4"], 4)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrIntMap()
m.Set("1", 1)
m.Set("2", 2)
t.Assert(m.Get("1"), 1)
t.Assert(m.Get("2"), 2)
data := m.Map()
t.Assert(data["1"], 1)
t.Assert(data["2"], 2)
data["3"] = 3
t.Assert(m.Get("3"), 3)
m.Set("4", 4)
t.Assert(data["4"], 4)
})
}
func Test_StrIntMap_MapCopy(t *testing.T) {
m := gmap.NewStrIntMap()
m.Set("1", 1)
m.Set("2", 2)
gtest.Assert(m.Get("1"), 1)
gtest.Assert(m.Get("2"), 2)
data := m.MapCopy()
gtest.Assert(data["1"], 1)
gtest.Assert(data["2"], 2)
data["3"] = 3
gtest.Assert(m.Get("3"), 0)
m.Set("4", 4)
gtest.Assert(data["4"], 0)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrIntMap()
m.Set("1", 1)
m.Set("2", 2)
t.Assert(m.Get("1"), 1)
t.Assert(m.Get("2"), 2)
data := m.MapCopy()
t.Assert(data["1"], 1)
t.Assert(data["2"], 2)
data["3"] = 3
t.Assert(m.Get("3"), 0)
m.Set("4", 4)
t.Assert(data["4"], 0)
})
}
func Test_StrIntMap_FilterEmpty(t *testing.T) {
m := gmap.NewStrIntMap()
m.Set("1", 0)
m.Set("2", 2)
gtest.Assert(m.Size(), 2)
gtest.Assert(m.Get("1"), 0)
gtest.Assert(m.Get("2"), 2)
m.FilterEmpty()
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get("2"), 2)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrIntMap()
m.Set("1", 0)
m.Set("2", 2)
t.Assert(m.Size(), 2)
t.Assert(m.Get("1"), 0)
t.Assert(m.Get("2"), 2)
m.FilterEmpty()
t.Assert(m.Size(), 1)
t.Assert(m.Get("2"), 2)
})
}
func Test_StrIntMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapStrInt{
"k1": 1,
"k2": 2,
@ -187,125 +203,125 @@ func Test_StrIntMap_Json(t *testing.T) {
m1 := gmap.NewStrIntMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapStrInt{
"k1": 1,
"k2": 2,
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
m := gmap.NewStrIntMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapStrInt{
"k1": 1,
"k2": 2,
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
var m gmap.StrIntMap
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
}
func Test_StrIntMap_Pop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrIntMapFrom(g.MapStrInt{
"k1": 11,
"k2": 22,
})
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
k1, v1 := m.Pop()
gtest.AssertIN(k1, g.Slice{"k1", "k2"})
gtest.AssertIN(v1, g.Slice{11, 22})
gtest.Assert(m.Size(), 1)
t.AssertIN(k1, g.Slice{"k1", "k2"})
t.AssertIN(v1, g.Slice{11, 22})
t.Assert(m.Size(), 1)
k2, v2 := m.Pop()
gtest.AssertIN(k2, g.Slice{"k1", "k2"})
gtest.AssertIN(v2, g.Slice{11, 22})
gtest.Assert(m.Size(), 0)
t.AssertIN(k2, g.Slice{"k1", "k2"})
t.AssertIN(v2, g.Slice{11, 22})
t.Assert(m.Size(), 0)
gtest.AssertNE(k1, k2)
gtest.AssertNE(v1, v2)
t.AssertNE(k1, k2)
t.AssertNE(v1, v2)
})
}
func Test_StrIntMap_Pops(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrIntMapFrom(g.MapStrInt{
"k1": 11,
"k2": 22,
"k3": 33,
})
gtest.Assert(m.Size(), 3)
t.Assert(m.Size(), 3)
kArray := garray.New()
vArray := garray.New()
for k, v := range m.Pops(1) {
gtest.AssertIN(k, g.Slice{"k1", "k2", "k3"})
gtest.AssertIN(v, g.Slice{11, 22, 33})
t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
t.AssertIN(v, g.Slice{11, 22, 33})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
for k, v := range m.Pops(2) {
gtest.AssertIN(k, g.Slice{"k1", "k2", "k3"})
gtest.AssertIN(v, g.Slice{11, 22, 33})
t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
t.AssertIN(v, g.Slice{11, 22, 33})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 0)
t.Assert(m.Size(), 0)
gtest.Assert(kArray.Unique().Len(), 3)
gtest.Assert(vArray.Unique().Len(), 3)
t.Assert(kArray.Unique().Len(), 3)
t.Assert(vArray.Unique().Len(), 3)
})
}
func TestStrIntMap_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Map *gmap.StrIntMap
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"k1":1,"k2":2}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), 1)
gtest.Assert(t.Map.Get("k2"), 2)
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("k1"), 1)
t.Assert(v.Map.Get("k2"), 2)
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.Map{
"k1": 1,
"k2": 2,
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), 1)
gtest.Assert(t.Map.Get("k2"), 2)
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("k1"), 1)
t.Assert(v.Map.Get("k2"), 2)
})
}

View File

@ -21,162 +21,179 @@ func stringStrCallBack(string, string) bool {
return true
}
func Test_StrStrMap_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrStrMap()
m.Set("a", "a")
gtest.Assert(m.Get("a"), "a")
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get("a"), "a")
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet("b", "b"), "b")
gtest.Assert(m.SetIfNotExist("b", "b"), false)
t.Assert(m.GetOrSet("b", "b"), "b")
t.Assert(m.SetIfNotExist("b", "b"), false)
gtest.Assert(m.SetIfNotExist("c", "c"), true)
t.Assert(m.SetIfNotExist("c", "c"), true)
gtest.Assert(m.Remove("b"), "b")
gtest.Assert(m.Contains("b"), false)
t.Assert(m.Remove("b"), "b")
t.Assert(m.Contains("b"), false)
gtest.AssertIN("c", m.Keys())
gtest.AssertIN("a", m.Keys())
gtest.AssertIN("a", m.Values())
gtest.AssertIN("c", m.Values())
t.AssertIN("c", m.Keys())
t.AssertIN("a", m.Keys())
t.AssertIN("a", m.Values())
t.AssertIN("c", m.Values())
m.Flip()
gtest.Assert(m.Map(), map[string]string{"a": "a", "c": "c"})
t.Assert(m.Map(), map[string]string{"a": "a", "c": "c"})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gmap.NewStrStrMapFrom(map[string]string{"a": "a", "b": "b"})
gtest.Assert(m2.Map(), map[string]string{"a": "a", "b": "b"})
t.Assert(m2.Map(), map[string]string{"a": "a", "b": "b"})
})
}
func Test_StrStrMap_Set_Fun(t *testing.T) {
m := gmap.NewStrStrMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrStrMap()
m.GetOrSetFunc("a", getStr)
m.GetOrSetFuncLock("b", getStr)
gtest.Assert(m.Get("a"), "z")
gtest.Assert(m.Get("b"), "z")
gtest.Assert(m.SetIfNotExistFunc("a", getStr), false)
gtest.Assert(m.SetIfNotExistFunc("c", getStr), true)
gtest.Assert(m.SetIfNotExistFuncLock("b", getStr), false)
gtest.Assert(m.SetIfNotExistFuncLock("d", getStr), true)
m.GetOrSetFunc("a", getStr)
m.GetOrSetFuncLock("b", getStr)
t.Assert(m.Get("a"), "z")
t.Assert(m.Get("b"), "z")
t.Assert(m.SetIfNotExistFunc("a", getStr), false)
t.Assert(m.SetIfNotExistFunc("c", getStr), true)
t.Assert(m.SetIfNotExistFuncLock("b", getStr), false)
t.Assert(m.SetIfNotExistFuncLock("d", getStr), true)
})
}
func Test_StrStrMap_Batch(t *testing.T) {
m := gmap.NewStrStrMap()
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrStrMap()
m.Sets(map[string]string{"a": "a", "b": "b", "c": "c"})
gtest.Assert(m.Map(), map[string]string{"a": "a", "b": "b", "c": "c"})
m.Removes([]string{"a", "b"})
gtest.Assert(m.Map(), map[string]string{"c": "c"})
m.Sets(map[string]string{"a": "a", "b": "b", "c": "c"})
t.Assert(m.Map(), map[string]string{"a": "a", "b": "b", "c": "c"})
m.Removes([]string{"a", "b"})
t.Assert(m.Map(), map[string]string{"c": "c"})
})
}
func Test_StrStrMap_Iterator(t *testing.T) {
expect := map[string]string{"a": "a", "b": "b"}
m := gmap.NewStrStrMapFrom(expect)
m.Iterator(func(k string, v string) bool {
gtest.Assert(expect[k], v)
return true
gtest.C(t, func(t *gtest.T) {
expect := map[string]string{"a": "a", "b": "b"}
m := gmap.NewStrStrMapFrom(expect)
m.Iterator(func(k string, v string) bool {
t.Assert(expect[k], v)
return true
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k string, v string) bool {
i++
return true
})
m.Iterator(func(k string, v string) bool {
j++
return false
})
t.Assert(i, 2)
t.Assert(j, 1)
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k string, v string) bool {
i++
return true
})
m.Iterator(func(k string, v string) bool {
j++
return false
})
gtest.Assert(i, 2)
gtest.Assert(j, 1)
}
func Test_StrStrMap_Lock(t *testing.T) {
expect := map[string]string{"a": "a", "b": "b"}
gtest.C(t, func(t *gtest.T) {
expect := map[string]string{"a": "a", "b": "b"}
m := gmap.NewStrStrMapFrom(expect)
m.LockFunc(func(m map[string]string) {
gtest.Assert(m, expect)
})
m.RLockFunc(func(m map[string]string) {
gtest.Assert(m, expect)
m := gmap.NewStrStrMapFrom(expect)
m.LockFunc(func(m map[string]string) {
t.Assert(m, expect)
})
m.RLockFunc(func(m map[string]string) {
t.Assert(m, expect)
})
})
}
func Test_StrStrMap_Clone(t *testing.T) {
//clone 方法是深克隆
m := gmap.NewStrStrMapFrom(map[string]string{"a": "a", "b": "b", "c": "c"})
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gmap.NewStrStrMapFrom(map[string]string{"a": "a", "b": "b", "c": "c"})
m_clone := m.Clone()
m.Remove("a")
//修改原 map,clone 后的 map 不影响
gtest.AssertIN("a", m_clone.Keys())
m_clone := m.Clone()
m.Remove("a")
//修改原 map,clone 后的 map 不影响
t.AssertIN("a", m_clone.Keys())
m_clone.Remove("b")
//修改clone map,原 map 不影响
gtest.AssertIN("b", m.Keys())
m_clone.Remove("b")
//修改clone map,原 map 不影响
t.AssertIN("b", m.Keys())
})
}
func Test_StrStrMap_Merge(t *testing.T) {
m1 := gmap.NewStrStrMap()
m2 := gmap.NewStrStrMap()
m1.Set("a", "a")
m2.Set("b", "b")
m1.Merge(m2)
gtest.Assert(m1.Map(), map[string]string{"a": "a", "b": "b"})
gtest.C(t, func(t *gtest.T) {
m1 := gmap.NewStrStrMap()
m2 := gmap.NewStrStrMap()
m1.Set("a", "a")
m2.Set("b", "b")
m1.Merge(m2)
t.Assert(m1.Map(), map[string]string{"a": "a", "b": "b"})
})
}
func Test_StrStrMap_Map(t *testing.T) {
m := gmap.NewStrStrMap()
m.Set("1", "1")
m.Set("2", "2")
gtest.Assert(m.Get("1"), "1")
gtest.Assert(m.Get("2"), "2")
data := m.Map()
gtest.Assert(data["1"], "1")
gtest.Assert(data["2"], "2")
data["3"] = "3"
gtest.Assert(m.Get("3"), "3")
m.Set("4", "4")
gtest.Assert(data["4"], "4")
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrStrMap()
m.Set("1", "1")
m.Set("2", "2")
t.Assert(m.Get("1"), "1")
t.Assert(m.Get("2"), "2")
data := m.Map()
t.Assert(data["1"], "1")
t.Assert(data["2"], "2")
data["3"] = "3"
t.Assert(m.Get("3"), "3")
m.Set("4", "4")
t.Assert(data["4"], "4")
})
}
func Test_StrStrMap_MapCopy(t *testing.T) {
m := gmap.NewStrStrMap()
m.Set("1", "1")
m.Set("2", "2")
gtest.Assert(m.Get("1"), "1")
gtest.Assert(m.Get("2"), "2")
data := m.MapCopy()
gtest.Assert(data["1"], "1")
gtest.Assert(data["2"], "2")
data["3"] = "3"
gtest.Assert(m.Get("3"), "")
m.Set("4", "4")
gtest.Assert(data["4"], "")
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrStrMap()
m.Set("1", "1")
m.Set("2", "2")
t.Assert(m.Get("1"), "1")
t.Assert(m.Get("2"), "2")
data := m.MapCopy()
t.Assert(data["1"], "1")
t.Assert(data["2"], "2")
data["3"] = "3"
t.Assert(m.Get("3"), "")
m.Set("4", "4")
t.Assert(data["4"], "")
})
}
func Test_StrStrMap_FilterEmpty(t *testing.T) {
m := gmap.NewStrStrMap()
m.Set("1", "")
m.Set("2", "2")
gtest.Assert(m.Size(), 2)
gtest.Assert(m.Get("1"), "")
gtest.Assert(m.Get("2"), "2")
m.FilterEmpty()
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get("2"), "2")
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrStrMap()
m.Set("1", "")
m.Set("2", "2")
t.Assert(m.Size(), 2)
t.Assert(m.Get("1"), "")
t.Assert(m.Get("2"), "2")
m.FilterEmpty()
t.Assert(m.Size(), 1)
t.Assert(m.Get("2"), "2")
})
}
func Test_StrStrMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapStrStr{
"k1": "v1",
"k2": "v2",
@ -184,125 +201,125 @@ func Test_StrStrMap_Json(t *testing.T) {
m1 := gmap.NewStrStrMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapStrStr{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
m := gmap.NewStrStrMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapStrStr{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
t.Assert(err, nil)
var m gmap.StrStrMap
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
}
func Test_StrStrMap_Pop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrStrMapFrom(g.MapStrStr{
"k1": "v1",
"k2": "v2",
})
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
k1, v1 := m.Pop()
gtest.AssertIN(k1, g.Slice{"k1", "k2"})
gtest.AssertIN(v1, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 1)
t.AssertIN(k1, g.Slice{"k1", "k2"})
t.AssertIN(v1, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 1)
k2, v2 := m.Pop()
gtest.AssertIN(k2, g.Slice{"k1", "k2"})
gtest.AssertIN(v2, g.Slice{"v1", "v2"})
gtest.Assert(m.Size(), 0)
t.AssertIN(k2, g.Slice{"k1", "k2"})
t.AssertIN(v2, g.Slice{"v1", "v2"})
t.Assert(m.Size(), 0)
gtest.AssertNE(k1, k2)
gtest.AssertNE(v1, v2)
t.AssertNE(k1, k2)
t.AssertNE(v1, v2)
})
}
func Test_StrStrMap_Pops(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewStrStrMapFrom(g.MapStrStr{
"k1": "v1",
"k2": "v2",
"k3": "v3",
})
gtest.Assert(m.Size(), 3)
t.Assert(m.Size(), 3)
kArray := garray.New()
vArray := garray.New()
for k, v := range m.Pops(1) {
gtest.AssertIN(k, g.Slice{"k1", "k2", "k3"})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 2)
t.Assert(m.Size(), 2)
for k, v := range m.Pops(2) {
gtest.AssertIN(k, g.Slice{"k1", "k2", "k3"})
gtest.AssertIN(v, g.Slice{"v1", "v2", "v3"})
t.AssertIN(k, g.Slice{"k1", "k2", "k3"})
t.AssertIN(v, g.Slice{"v1", "v2", "v3"})
kArray.Append(k)
vArray.Append(v)
}
gtest.Assert(m.Size(), 0)
t.Assert(m.Size(), 0)
gtest.Assert(kArray.Unique().Len(), 3)
gtest.Assert(vArray.Unique().Len(), 3)
t.Assert(kArray.Unique().Len(), 3)
t.Assert(vArray.Unique().Len(), 3)
})
}
func TestStrStrMap_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Map *gmap.StrStrMap
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"k1":"v1","k2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("k1"), "v1")
t.Assert(v.Map.Get("k2"), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.Map{
"k1": "v1",
"k2": "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("k1"), "v1")
t.Assert(v.Map.Get("k2"), "v2")
})
}

View File

@ -18,96 +18,122 @@ import (
)
func Test_TreeMap_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gmap.NewTreeMap(gutil.ComparatorString)
m.Set("key1", "val1")
gtest.Assert(m.Keys(), []interface{}{"key1"})
t.Assert(m.Keys(), []interface{}{"key1"})
gtest.Assert(m.Get("key1"), "val1")
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get("key1"), "val1")
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet("key2", "val2"), "val2")
gtest.Assert(m.SetIfNotExist("key2", "val2"), false)
t.Assert(m.GetOrSet("key2", "val2"), "val2")
t.Assert(m.SetIfNotExist("key2", "val2"), false)
gtest.Assert(m.SetIfNotExist("key3", "val3"), true)
t.Assert(m.SetIfNotExist("key3", "val3"), true)
gtest.Assert(m.Remove("key2"), "val2")
gtest.Assert(m.Contains("key2"), false)
t.Assert(m.Remove("key2"), "val2")
t.Assert(m.Contains("key2"), false)
gtest.AssertIN("key3", m.Keys())
gtest.AssertIN("key1", m.Keys())
gtest.AssertIN("val3", m.Values())
gtest.AssertIN("val1", m.Values())
t.AssertIN("key3", m.Keys())
t.AssertIN("key1", m.Keys())
t.AssertIN("val3", m.Values())
t.AssertIN("val1", m.Values())
m.Flip()
gtest.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val1": "key1"})
t.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val1": "key1"})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gmap.NewTreeMapFrom(gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
t.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
})
}
func Test_TreeMap_Set_Fun(t *testing.T) {
m := gmap.NewTreeMap(gutil.ComparatorString)
m.GetOrSetFunc("fun", getValue)
m.GetOrSetFuncLock("funlock", getValue)
gtest.Assert(m.Get("funlock"), 3)
gtest.Assert(m.Get("fun"), 3)
m.GetOrSetFunc("fun", getValue)
gtest.Assert(m.SetIfNotExistFunc("fun", getValue), false)
gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
gtest.C(t, func(t *gtest.T) {
m := gmap.NewTreeMap(gutil.ComparatorString)
m.GetOrSetFunc("fun", getValue)
m.GetOrSetFuncLock("funlock", getValue)
t.Assert(m.Get("funlock"), 3)
t.Assert(m.Get("fun"), 3)
m.GetOrSetFunc("fun", getValue)
t.Assert(m.SetIfNotExistFunc("fun", getValue), false)
t.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
})
}
func Test_TreeMap_Batch(t *testing.T) {
m := gmap.NewTreeMap(gutil.ComparatorString)
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
gtest.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
gtest.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
gtest.C(t, func(t *gtest.T) {
m := gmap.NewTreeMap(gutil.ComparatorString)
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
t.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
t.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
})
}
func Test_TreeMap_Iterator(t *testing.T) {
expect := map[interface{}]interface{}{1: 1, "key1": "val1"}
gtest.C(t, func(t *gtest.T) {
expect := map[interface{}]interface{}{1: 1, "key1": "val1"}
m := gmap.NewTreeMapFrom(gutil.ComparatorString, expect)
m.Iterator(func(k interface{}, v interface{}) bool {
t.Assert(expect[k], v)
return true
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k interface{}, v interface{}) bool {
i++
return true
})
m.Iterator(func(k interface{}, v interface{}) bool {
j++
return false
})
t.Assert(i, 2)
t.Assert(j, 1)
})
m := gmap.NewTreeMapFrom(gutil.ComparatorString, expect)
m.Iterator(func(k interface{}, v interface{}) bool {
gtest.Assert(expect[k], v)
return true
gtest.C(t, func(t *gtest.T) {
expect := map[interface{}]interface{}{1: 1, "key1": "val1"}
m := gmap.NewTreeMapFrom(gutil.ComparatorString, expect)
for i := 0; i < 10; i++ {
m.IteratorAsc(func(k interface{}, v interface{}) bool {
t.Assert(expect[k], v)
return true
})
}
j := 0
for i := 0; i < 10; i++ {
m.IteratorAsc(func(k interface{}, v interface{}) bool {
j++
return false
})
}
t.Assert(j, 10)
})
// 断言返回值对遍历控制
i := 0
j := 0
m.Iterator(func(k interface{}, v interface{}) bool {
i++
return true
})
m.Iterator(func(k interface{}, v interface{}) bool {
j++
return false
})
gtest.Assert(i, 2)
gtest.Assert(j, 1)
}
func Test_TreeMap_Clone(t *testing.T) {
//clone 方法是深克隆
m := gmap.NewTreeMapFrom(gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
gtest.AssertIN(1, m_clone.Keys())
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gmap.NewTreeMapFrom(gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
t.AssertIN(1, m_clone.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
gtest.AssertIN("key1", m.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
t.AssertIN("key1", m.Keys())
})
}
func Test_TreeMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
@ -115,72 +141,72 @@ func Test_TreeMap_Json(t *testing.T) {
m1 := gmap.NewTreeMapFrom(gutil.ComparatorString, data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(gconv.Map(data))
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
t.Assert(err, nil)
m := gmap.NewTreeMap(gutil.ComparatorString)
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
t.Assert(err, nil)
var m gmap.TreeMap
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
t.Assert(err, nil)
t.Assert(m.Get("k1"), data["k1"])
t.Assert(m.Get("k2"), data["k2"])
})
}
func TestTreeMap_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Map *gmap.TreeMap
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"k1":"v1","k2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("k1"), "v1")
t.Assert(v.Map.Get("k2"), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.Map{
"k1": "v1",
"k2": "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Map.Size(), 2)
t.Assert(v.Map.Get("k1"), "v1")
t.Assert(v.Map.Get("k2"), "v2")
})
}

View File

@ -28,7 +28,7 @@ var ef gpool.ExpireFunc = func(i interface{}) {
}
func Test_Gpool(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
//
//expire = 0
p1 := gpool.New(0, nf)
@ -37,63 +37,63 @@ func Test_Gpool(t *testing.T) {
time.Sleep(1 * time.Second)
//test won't be timeout
v1, err1 := p1.Get()
gtest.Assert(err1, nil)
gtest.AssertIN(v1, g.Slice{1, 2})
t.Assert(err1, nil)
t.AssertIN(v1, g.Slice{1, 2})
//test clear
p1.Clear()
gtest.Assert(p1.Size(), 0)
t.Assert(p1.Size(), 0)
//test newFunc
v1, err1 = p1.Get()
gtest.Assert(err1, nil)
gtest.Assert(v1, "hello")
t.Assert(err1, nil)
t.Assert(v1, "hello")
//put data again
p1.Put(3)
p1.Put(4)
v1, err1 = p1.Get()
gtest.Assert(err1, nil)
gtest.AssertIN(v1, g.Slice{3, 4})
t.Assert(err1, nil)
t.AssertIN(v1, g.Slice{3, 4})
//test close
p1.Close()
v1, err1 = p1.Get()
gtest.Assert(err1, nil)
gtest.Assert(v1, "hello")
t.Assert(err1, nil)
t.Assert(v1, "hello")
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
//
//expire > 0
p2 := gpool.New(2*time.Second, nil, ef)
for index := 0; index < 10; index++ {
p2.Put(index)
}
gtest.Assert(p2.Size(), 10)
t.Assert(p2.Size(), 10)
v2, err2 := p2.Get()
gtest.Assert(err2, nil)
gtest.Assert(v2, 0)
t.Assert(err2, nil)
t.Assert(v2, 0)
//test timeout expireFunc
time.Sleep(3 * time.Second)
v2, err2 = p2.Get()
gtest.Assert(err2, errors.New("pool is empty"))
gtest.Assert(v2, nil)
t.Assert(err2, errors.New("pool is empty"))
t.Assert(v2, nil)
//test close expireFunc
for index := 0; index < 10; index++ {
p2.Put(index)
}
gtest.Assert(p2.Size(), 10)
t.Assert(p2.Size(), 10)
v2, err2 = p2.Get()
gtest.Assert(err2, nil)
gtest.Assert(v2, 0)
t.Assert(err2, nil)
t.Assert(v2, 0)
assertIndex = 0
p2.Close()
time.Sleep(3 * time.Second)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
//
//expire < 0
p3 := gpool.New(-1, nil)
v3, err3 := p3.Get()
gtest.Assert(err3, errors.New("pool is empty"))
gtest.Assert(v3, nil)
t.Assert(err3, errors.New("pool is empty"))
t.Assert(v3, nil)
})
}

View File

@ -17,41 +17,49 @@ import (
)
func TestQueue_Len(t *testing.T) {
max := 100
for n := 10; n < max; n++ {
q1 := gqueue.New(max)
for i := 0; i < max; i++ {
q1.Push(i)
gtest.C(t, func(t *gtest.T) {
max := 100
for n := 10; n < max; n++ {
q1 := gqueue.New(max)
for i := 0; i < max; i++ {
q1.Push(i)
}
t.Assert(q1.Len(), max)
t.Assert(q1.Size(), max)
}
gtest.Assert(q1.Len(), max)
gtest.Assert(q1.Size(), max)
}
})
}
func TestQueue_Basic(t *testing.T) {
q := gqueue.New()
for i := 0; i < 100; i++ {
q.Push(i)
}
gtest.Assert(q.Pop(), 0)
gtest.Assert(q.Pop(), 1)
gtest.C(t, func(t *gtest.T) {
q := gqueue.New()
for i := 0; i < 100; i++ {
q.Push(i)
}
t.Assert(q.Pop(), 0)
t.Assert(q.Pop(), 1)
})
}
func TestQueue_Pop(t *testing.T) {
q1 := gqueue.New()
q1.Push(1)
q1.Push(2)
q1.Push(3)
q1.Push(4)
i1 := q1.Pop()
gtest.Assert(i1, 1)
gtest.C(t, func(t *gtest.T) {
q1 := gqueue.New()
q1.Push(1)
q1.Push(2)
q1.Push(3)
q1.Push(4)
i1 := q1.Pop()
t.Assert(i1, 1)
})
}
func TestQueue_Close(t *testing.T) {
q1 := gqueue.New()
q1.Push(1)
q1.Push(2)
time.Sleep(time.Millisecond)
gtest.Assert(q1.Len(), 2)
q1.Close()
gtest.C(t, func(t *gtest.T) {
q1 := gqueue.New()
q1.Push(1)
q1.Push(2)
time.Sleep(time.Millisecond)
t.Assert(q1.Len(), 2)
q1.Close()
})
}

View File

@ -16,7 +16,7 @@ type Student struct {
}
func TestRing_Val(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
//定义cap 为3的ring类型数据
r := gring.New(3, true)
//分别给3个元素初始化赋值
@ -25,46 +25,46 @@ func TestRing_Val(t *testing.T) {
r.Put(&Student{3, "alon", false})
//元素取值并判断和预设值是否相等
gtest.Assert(r.Val().(*Student).name, "jimmy")
t.Assert(r.Val().(*Student).name, "jimmy")
//从当前位置往后移两个元素
r.Move(2)
gtest.Assert(r.Val().(*Student).name, "alon")
t.Assert(r.Val().(*Student).name, "alon")
//更新元素值
//测试 value == nil
r.Set(nil)
gtest.Assert(r.Val(), nil)
t.Assert(r.Val(), nil)
//测试value != nil
r.Set(&Student{3, "jack", true})
})
}
func TestRing_CapLen(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
r := gring.New(10)
r.Put("goframe")
//cap长度 10
gtest.Assert(r.Cap(), 10)
t.Assert(r.Cap(), 10)
//已有数据项 1
gtest.Assert(r.Len(), 1)
t.Assert(r.Len(), 1)
})
}
func TestRing_Position(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
r := gring.New(2)
r.Put(1)
r.Put(2)
//往后移动1个元素
r.Next()
gtest.Assert(r.Val(), 2)
t.Assert(r.Val(), 2)
//往前移动1个元素
r.Prev()
gtest.Assert(r.Val(), 1)
t.Assert(r.Val(), 1)
})
}
func TestRing_Link(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
r := gring.New(3)
r.Put(1)
r.Put(2)
@ -74,13 +74,13 @@ func TestRing_Link(t *testing.T) {
s.Put("b")
rs := r.Link(s)
gtest.Assert(rs.Move(2).Val(), "b")
t.Assert(rs.Move(2).Val(), "b")
})
}
func TestRing_Unlink(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
r := gring.New(5)
for i := 0; i < 5; i++ {
r.Put(i + 1)
@ -89,13 +89,13 @@ func TestRing_Unlink(t *testing.T) {
// 删除当前位置往后的2个数据返回被删除的数据
// 重新计算s len
s := r.Unlink(2) // 2 3
gtest.Assert(s.Val(), 2)
gtest.Assert(s.Len(), 1)
t.Assert(s.Val(), 2)
t.Assert(s.Len(), 1)
})
}
func TestRing_Slice(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
ringLen := 5
r := gring.New(ringLen)
for i := 0; i < ringLen; i++ {
@ -103,49 +103,49 @@ func TestRing_Slice(t *testing.T) {
}
r.Move(2) // 3
array := r.SliceNext() // [3 4 5 1 2]
gtest.Assert(array[0], 3)
gtest.Assert(len(array), 5)
t.Assert(array[0], 3)
t.Assert(len(array), 5)
//判断array是否等于[3 4 5 1 2]
ra := []int{3, 4, 5, 1, 2}
gtest.Assert(ra, array)
t.Assert(ra, array)
//第3个元素设为nil
r.Set(nil)
array2 := r.SliceNext() //[4 5 1 2]
//返回当前位置往后不为空的元素数组长度为4
gtest.Assert(array2, g.Slice{4, 5, 1, 2})
t.Assert(array2, g.Slice{4, 5, 1, 2})
array3 := r.SlicePrev() //[2 1 5 4]
gtest.Assert(array3, g.Slice{2, 1, 5, 4})
t.Assert(array3, g.Slice{2, 1, 5, 4})
s := gring.New(ringLen)
for i := 0; i < ringLen; i++ {
s.Put(i + 1)
}
array4 := s.SlicePrev() // []
gtest.Assert(array4, g.Slice{1, 5, 4, 3, 2})
t.Assert(array4, g.Slice{1, 5, 4, 3, 2})
})
}
func TestRing_RLockIterator(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
ringLen := 5
r := gring.New(ringLen)
//ring不存在有值元素
r.RLockIteratorNext(func(v interface{}) bool {
gtest.Assert(v, nil)
t.Assert(v, nil)
return false
})
r.RLockIteratorNext(func(v interface{}) bool {
gtest.Assert(v, nil)
t.Assert(v, nil)
return true
})
r.RLockIteratorPrev(func(v interface{}) bool {
gtest.Assert(v, nil)
t.Assert(v, nil)
return true
})
@ -156,14 +156,14 @@ func TestRing_RLockIterator(t *testing.T) {
//回调函数返回true,RLockIteratorNext遍历5次,期望值分别是1、2、3、4、5
i := 0
r.RLockIteratorNext(func(v interface{}) bool {
gtest.Assert(v, i+1)
t.Assert(v, i+1)
i++
return true
})
//RLockIteratorPrev遍历1次返回 false,退出遍历
r.RLockIteratorPrev(func(v interface{}) bool {
gtest.Assert(v, 1)
t.Assert(v, 1)
return false
})
@ -171,30 +171,30 @@ func TestRing_RLockIterator(t *testing.T) {
}
func TestRing_LockIterator(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
ringLen := 5
r := gring.New(ringLen)
//不存在有值元素
r.LockIteratorNext(func(item *ring.Ring) bool {
gtest.Assert(item.Value, nil)
t.Assert(item.Value, nil)
return false
})
r.LockIteratorNext(func(item *ring.Ring) bool {
gtest.Assert(item.Value, nil)
t.Assert(item.Value, nil)
return false
})
r.LockIteratorNext(func(item *ring.Ring) bool {
gtest.Assert(item.Value, nil)
t.Assert(item.Value, nil)
return true
})
r.LockIteratorPrev(func(item *ring.Ring) bool {
gtest.Assert(item.Value, nil)
t.Assert(item.Value, nil)
return false
})
r.LockIteratorPrev(func(item *ring.Ring) bool {
gtest.Assert(item.Value, nil)
t.Assert(item.Value, nil)
return true
})
@ -208,7 +208,7 @@ func TestRing_LockIterator(t *testing.T) {
ii := 0
r.LockIteratorNext(func(item *ring.Ring) bool {
//校验每一次遍历取值是否是期望值
gtest.Assert(item.Value, array1[ii])
t.Assert(item.Value, array1[ii])
ii++
return true
})
@ -221,7 +221,7 @@ func TestRing_LockIterator(t *testing.T) {
if i > 2 {
return false
}
gtest.Assert(item.Value, a[i])
t.Assert(item.Value, a[i])
i++
return true
})

View File

@ -22,50 +22,50 @@ import (
)
func TestSet_New(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.New()
s.Add(1).Add(1).Add(2)
s.Add([]interface{}{3, 4}...)
gtest.Assert(s.Size(), 4)
gtest.AssertIN(1, s.Slice())
gtest.AssertIN(2, s.Slice())
gtest.AssertIN(3, s.Slice())
gtest.AssertIN(4, s.Slice())
gtest.AssertNI(0, s.Slice())
gtest.Assert(s.Contains(4), true)
gtest.Assert(s.Contains(5), false)
t.Assert(s.Size(), 4)
t.AssertIN(1, s.Slice())
t.AssertIN(2, s.Slice())
t.AssertIN(3, s.Slice())
t.AssertIN(4, s.Slice())
t.AssertNI(0, s.Slice())
t.Assert(s.Contains(4), true)
t.Assert(s.Contains(5), false)
s.Remove(1)
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 3)
s.Clear()
gtest.Assert(s.Size(), 0)
t.Assert(s.Size(), 0)
})
}
func TestSet_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewSet()
s.Add(1).Add(1).Add(2)
s.Add([]interface{}{3, 4}...)
gtest.Assert(s.Size(), 4)
gtest.AssertIN(1, s.Slice())
gtest.AssertIN(2, s.Slice())
gtest.AssertIN(3, s.Slice())
gtest.AssertIN(4, s.Slice())
gtest.AssertNI(0, s.Slice())
gtest.Assert(s.Contains(4), true)
gtest.Assert(s.Contains(5), false)
t.Assert(s.Size(), 4)
t.AssertIN(1, s.Slice())
t.AssertIN(2, s.Slice())
t.AssertIN(3, s.Slice())
t.AssertIN(4, s.Slice())
t.AssertNI(0, s.Slice())
t.Assert(s.Contains(4), true)
t.Assert(s.Contains(5), false)
s.Remove(1)
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 3)
s.Clear()
gtest.Assert(s.Size(), 0)
t.Assert(s.Size(), 0)
})
}
func TestSet_Iterator(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewSet()
s.Add(1).Add(2).Add(3)
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 3)
a1 := garray.New(true)
a2 := garray.New(true)
@ -77,22 +77,22 @@ func TestSet_Iterator(t *testing.T) {
a2.Append(1)
return true
})
gtest.Assert(a1.Len(), 1)
gtest.Assert(a2.Len(), 3)
t.Assert(a1.Len(), 1)
t.Assert(a2.Len(), 3)
})
}
func TestSet_LockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewSet()
s.Add(1).Add(2).Add(3)
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 3)
s.LockFunc(func(m map[interface{}]struct{}) {
delete(m, 1)
})
gtest.Assert(s.Size(), 2)
t.Assert(s.Size(), 2)
s.RLockFunc(func(m map[interface{}]struct{}) {
gtest.Assert(m, map[interface{}]struct{}{
t.Assert(m, map[interface{}]struct{}{
3: struct{}{},
2: struct{}{},
})
@ -101,302 +101,302 @@ func TestSet_LockFunc(t *testing.T) {
}
func TestSet_Equal(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewSet()
s2 := gset.NewSet()
s3 := gset.NewSet()
s1.Add(1).Add(2).Add(3)
s2.Add(1).Add(2).Add(3)
s3.Add(1).Add(2).Add(3).Add(4)
gtest.Assert(s1.Equal(s2), true)
gtest.Assert(s1.Equal(s3), false)
t.Assert(s1.Equal(s2), true)
t.Assert(s1.Equal(s3), false)
})
}
func TestSet_IsSubsetOf(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewSet()
s2 := gset.NewSet()
s3 := gset.NewSet()
s1.Add(1).Add(2)
s2.Add(1).Add(2).Add(3)
s3.Add(1).Add(2).Add(3).Add(4)
gtest.Assert(s1.IsSubsetOf(s2), true)
gtest.Assert(s2.IsSubsetOf(s3), true)
gtest.Assert(s1.IsSubsetOf(s3), true)
gtest.Assert(s2.IsSubsetOf(s1), false)
gtest.Assert(s3.IsSubsetOf(s2), false)
t.Assert(s1.IsSubsetOf(s2), true)
t.Assert(s2.IsSubsetOf(s3), true)
t.Assert(s1.IsSubsetOf(s3), true)
t.Assert(s2.IsSubsetOf(s1), false)
t.Assert(s3.IsSubsetOf(s2), false)
})
}
func TestSet_Union(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewSet()
s2 := gset.NewSet()
s1.Add(1).Add(2)
s2.Add(3).Add(4)
s3 := s1.Union(s2)
gtest.Assert(s3.Contains(1), true)
gtest.Assert(s3.Contains(2), true)
gtest.Assert(s3.Contains(3), true)
gtest.Assert(s3.Contains(4), true)
t.Assert(s3.Contains(1), true)
t.Assert(s3.Contains(2), true)
t.Assert(s3.Contains(3), true)
t.Assert(s3.Contains(4), true)
})
}
func TestSet_Diff(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewSet()
s2 := gset.NewSet()
s1.Add(1).Add(2).Add(3)
s2.Add(3).Add(4).Add(5)
s3 := s1.Diff(s2)
gtest.Assert(s3.Contains(1), true)
gtest.Assert(s3.Contains(2), true)
gtest.Assert(s3.Contains(3), false)
gtest.Assert(s3.Contains(4), false)
t.Assert(s3.Contains(1), true)
t.Assert(s3.Contains(2), true)
t.Assert(s3.Contains(3), false)
t.Assert(s3.Contains(4), false)
})
}
func TestSet_Intersect(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewSet()
s2 := gset.NewSet()
s1.Add(1).Add(2).Add(3)
s2.Add(3).Add(4).Add(5)
s3 := s1.Intersect(s2)
gtest.Assert(s3.Contains(1), false)
gtest.Assert(s3.Contains(2), false)
gtest.Assert(s3.Contains(3), true)
gtest.Assert(s3.Contains(4), false)
t.Assert(s3.Contains(1), false)
t.Assert(s3.Contains(2), false)
t.Assert(s3.Contains(3), true)
t.Assert(s3.Contains(4), false)
})
}
func TestSet_Complement(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewSet()
s2 := gset.NewSet()
s1.Add(1).Add(2).Add(3)
s2.Add(3).Add(4).Add(5)
s3 := s1.Complement(s2)
gtest.Assert(s3.Contains(1), false)
gtest.Assert(s3.Contains(2), false)
gtest.Assert(s3.Contains(4), true)
gtest.Assert(s3.Contains(5), true)
t.Assert(s3.Contains(1), false)
t.Assert(s3.Contains(2), false)
t.Assert(s3.Contains(4), true)
t.Assert(s3.Contains(5), true)
})
}
func TestNewFrom(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewFrom("a")
s2 := gset.NewFrom("b", false)
s3 := gset.NewFrom(3, true)
s4 := gset.NewFrom([]string{"s1", "s2"}, true)
gtest.Assert(s1.Contains("a"), true)
gtest.Assert(s2.Contains("b"), true)
gtest.Assert(s3.Contains(3), true)
gtest.Assert(s4.Contains("s1"), true)
gtest.Assert(s4.Contains("s3"), false)
t.Assert(s1.Contains("a"), true)
t.Assert(s2.Contains("b"), true)
t.Assert(s3.Contains(3), true)
t.Assert(s4.Contains("s1"), true)
t.Assert(s4.Contains("s3"), false)
})
}
func TestNew(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.New()
s1.Add("a").Add(2)
s2 := gset.New(true)
s2.Add("b").Add(3)
gtest.Assert(s1.Contains("a"), true)
t.Assert(s1.Contains("a"), true)
})
}
func TestSet_Join(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.New(true)
s1.Add("a").Add("a1").Add("b").Add("c")
str1 := s1.Join(",")
gtest.Assert(strings.Contains(str1, "a1"), true)
t.Assert(strings.Contains(str1, "a1"), true)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.New(true)
s1.Add("a").Add(`"b"`).Add(`\c`)
str1 := s1.Join(",")
gtest.Assert(strings.Contains(str1, `"b"`), true)
gtest.Assert(strings.Contains(str1, `\c`), true)
gtest.Assert(strings.Contains(str1, `a`), true)
t.Assert(strings.Contains(str1, `"b"`), true)
t.Assert(strings.Contains(str1, `\c`), true)
t.Assert(strings.Contains(str1, `a`), true)
})
}
func TestSet_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.New(true)
s1.Add("a").Add("a2").Add("b").Add("c")
str1 := s1.String()
gtest.Assert(strings.Contains(str1, "["), true)
gtest.Assert(strings.Contains(str1, "]"), true)
gtest.Assert(strings.Contains(str1, "a2"), true)
t.Assert(strings.Contains(str1, "["), true)
t.Assert(strings.Contains(str1, "]"), true)
t.Assert(strings.Contains(str1, "a2"), true)
})
}
func TestSet_Merge(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.New(true)
s2 := gset.New(true)
s1.Add("a").Add("a2").Add("b").Add("c")
s2.Add("b").Add("b1").Add("e").Add("f")
ss := s1.Merge(s2)
gtest.Assert(ss.Contains("a2"), true)
gtest.Assert(ss.Contains("b1"), true)
t.Assert(ss.Contains("a2"), true)
t.Assert(ss.Contains("b1"), true)
})
}
func TestSet_Sum(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.New(true)
s1.Add(1).Add(2).Add(3).Add(4)
gtest.Assert(s1.Sum(), int(10))
t.Assert(s1.Sum(), int(10))
})
}
func TestSet_Pop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.New(true)
s.Add(1).Add(2).Add(3).Add(4)
gtest.Assert(s.Size(), 4)
gtest.AssertIN(s.Pop(), []int{1, 2, 3, 4})
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 4)
t.AssertIN(s.Pop(), []int{1, 2, 3, 4})
t.Assert(s.Size(), 3)
})
}
func TestSet_Pops(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.New(true)
s.Add(1).Add(2).Add(3).Add(4)
gtest.Assert(s.Size(), 4)
gtest.Assert(s.Pops(0), nil)
gtest.AssertIN(s.Pops(1), []int{1, 2, 3, 4})
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 4)
t.Assert(s.Pops(0), nil)
t.AssertIN(s.Pops(1), []int{1, 2, 3, 4})
t.Assert(s.Size(), 3)
a := s.Pops(6)
gtest.Assert(len(a), 3)
gtest.AssertIN(a, []int{1, 2, 3, 4})
gtest.Assert(s.Size(), 0)
t.Assert(len(a), 3)
t.AssertIN(a, []int{1, 2, 3, 4})
t.Assert(s.Size(), 0)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.New(true)
a := []interface{}{1, 2, 3, 4}
s.Add(a...)
gtest.Assert(s.Size(), 4)
gtest.Assert(s.Pops(-2), nil)
gtest.AssertIN(s.Pops(-1), a)
t.Assert(s.Size(), 4)
t.Assert(s.Pops(-2), nil)
t.AssertIN(s.Pops(-1), a)
})
}
func TestSet_Json(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []interface{}{"a", "b", "d", "c"}
a1 := gset.NewFrom(s1)
b1, err1 := json.Marshal(a1)
b2, err2 := json.Marshal(s1)
gtest.Assert(len(b1), len(b2))
gtest.Assert(err1, err2)
t.Assert(len(b1), len(b2))
t.Assert(err1, err2)
a2 := gset.New()
err2 = json.Unmarshal(b2, &a2)
gtest.Assert(err2, nil)
gtest.Assert(a2.Contains("a"), true)
gtest.Assert(a2.Contains("b"), true)
gtest.Assert(a2.Contains("c"), true)
gtest.Assert(a2.Contains("d"), true)
gtest.Assert(a2.Contains("e"), false)
t.Assert(err2, nil)
t.Assert(a2.Contains("a"), true)
t.Assert(a2.Contains("b"), true)
t.Assert(a2.Contains("c"), true)
t.Assert(a2.Contains("d"), true)
t.Assert(a2.Contains("e"), false)
var a3 gset.Set
err := json.Unmarshal(b2, &a3)
gtest.Assert(err, nil)
gtest.Assert(a3.Contains("a"), true)
gtest.Assert(a3.Contains("b"), true)
gtest.Assert(a3.Contains("c"), true)
gtest.Assert(a3.Contains("d"), true)
gtest.Assert(a3.Contains("e"), false)
t.Assert(err, nil)
t.Assert(a3.Contains("a"), true)
t.Assert(a3.Contains("b"), true)
t.Assert(a3.Contains("c"), true)
t.Assert(a3.Contains("d"), true)
t.Assert(a3.Contains("e"), false)
})
}
func TestSet_AddIfNotExistFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.New(true)
s.Add(1)
gtest.Assert(s.Contains(1), true)
gtest.Assert(s.Contains(2), false)
t.Assert(s.Contains(1), true)
t.Assert(s.Contains(2), false)
s.AddIfNotExistFunc(2, func() interface{} {
return 3
})
gtest.Assert(s.Contains(2), false)
gtest.Assert(s.Contains(3), true)
t.Assert(s.Contains(2), false)
t.Assert(s.Contains(3), true)
s.AddIfNotExistFunc(3, func() interface{} {
return 4
})
gtest.Assert(s.Contains(3), true)
gtest.Assert(s.Contains(4), false)
t.Assert(s.Contains(3), true)
t.Assert(s.Contains(4), false)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.New(true)
s.Add(1)
gtest.Assert(s.Contains(1), true)
gtest.Assert(s.Contains(2), false)
t.Assert(s.Contains(1), true)
t.Assert(s.Contains(2), false)
s.AddIfNotExistFuncLock(2, func() interface{} {
return 3
})
gtest.Assert(s.Contains(2), false)
gtest.Assert(s.Contains(3), true)
t.Assert(s.Contains(2), false)
t.Assert(s.Contains(3), true)
s.AddIfNotExistFuncLock(3, func() interface{} {
return 4
})
gtest.Assert(s.Contains(3), true)
gtest.Assert(s.Contains(4), false)
t.Assert(s.Contains(3), true)
t.Assert(s.Contains(4), false)
})
}
func TestSet_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Set *gset.Set
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"set": []byte(`["k1","k2","k3"]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains("k1"), true)
gtest.Assert(t.Set.Contains("k2"), true)
gtest.Assert(t.Set.Contains("k3"), true)
gtest.Assert(t.Set.Contains("k4"), false)
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Set.Size(), 3)
t.Assert(v.Set.Contains("k1"), true)
t.Assert(v.Set.Contains("k2"), true)
t.Assert(v.Set.Contains("k3"), true)
t.Assert(v.Set.Contains("k4"), false)
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"set": g.Slice{"k1", "k2", "k3"},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains("k1"), true)
gtest.Assert(t.Set.Contains("k2"), true)
gtest.Assert(t.Set.Contains("k3"), true)
gtest.Assert(t.Set.Contains("k4"), false)
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Set.Size(), 3)
t.Assert(v.Set.Contains("k1"), true)
t.Assert(v.Set.Contains("k2"), true)
t.Assert(v.Set.Contains("k3"), true)
t.Assert(v.Set.Contains("k4"), false)
})
}

View File

@ -21,30 +21,30 @@ import (
)
func TestIntSet_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewIntSet()
s.Add(1).Add(1).Add(2)
s.Add([]int{3, 4}...)
gtest.Assert(s.Size(), 4)
gtest.AssertIN(1, s.Slice())
gtest.AssertIN(2, s.Slice())
gtest.AssertIN(3, s.Slice())
gtest.AssertIN(4, s.Slice())
gtest.AssertNI(0, s.Slice())
gtest.Assert(s.Contains(4), true)
gtest.Assert(s.Contains(5), false)
t.Assert(s.Size(), 4)
t.AssertIN(1, s.Slice())
t.AssertIN(2, s.Slice())
t.AssertIN(3, s.Slice())
t.AssertIN(4, s.Slice())
t.AssertNI(0, s.Slice())
t.Assert(s.Contains(4), true)
t.Assert(s.Contains(5), false)
s.Remove(1)
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 3)
s.Clear()
gtest.Assert(s.Size(), 0)
t.Assert(s.Size(), 0)
})
}
func TestIntSet_Iterator(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewIntSet()
s.Add(1).Add(2).Add(3)
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 3)
a1 := garray.New(true)
a2 := garray.New(true)
@ -56,22 +56,22 @@ func TestIntSet_Iterator(t *testing.T) {
a2.Append(1)
return true
})
gtest.Assert(a1.Len(), 1)
gtest.Assert(a2.Len(), 3)
t.Assert(a1.Len(), 1)
t.Assert(a2.Len(), 3)
})
}
func TestIntSet_LockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewIntSet()
s.Add(1).Add(2).Add(3)
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 3)
s.LockFunc(func(m map[int]struct{}) {
delete(m, 1)
})
gtest.Assert(s.Size(), 2)
t.Assert(s.Size(), 2)
s.RLockFunc(func(m map[int]struct{}) {
gtest.Assert(m, map[int]struct{}{
t.Assert(m, map[int]struct{}{
3: struct{}{},
2: struct{}{},
})
@ -80,286 +80,286 @@ func TestIntSet_LockFunc(t *testing.T) {
}
func TestIntSet_Equal(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSet()
s2 := gset.NewIntSet()
s3 := gset.NewIntSet()
s1.Add(1).Add(2).Add(3)
s2.Add(1).Add(2).Add(3)
s3.Add(1).Add(2).Add(3).Add(4)
gtest.Assert(s1.Equal(s2), true)
gtest.Assert(s1.Equal(s3), false)
t.Assert(s1.Equal(s2), true)
t.Assert(s1.Equal(s3), false)
})
}
func TestIntSet_IsSubsetOf(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSet()
s2 := gset.NewIntSet()
s3 := gset.NewIntSet()
s1.Add(1).Add(2)
s2.Add(1).Add(2).Add(3)
s3.Add(1).Add(2).Add(3).Add(4)
gtest.Assert(s1.IsSubsetOf(s2), true)
gtest.Assert(s2.IsSubsetOf(s3), true)
gtest.Assert(s1.IsSubsetOf(s3), true)
gtest.Assert(s2.IsSubsetOf(s1), false)
gtest.Assert(s3.IsSubsetOf(s2), false)
t.Assert(s1.IsSubsetOf(s2), true)
t.Assert(s2.IsSubsetOf(s3), true)
t.Assert(s1.IsSubsetOf(s3), true)
t.Assert(s2.IsSubsetOf(s1), false)
t.Assert(s3.IsSubsetOf(s2), false)
})
}
func TestIntSet_Union(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSet()
s2 := gset.NewIntSet()
s1.Add(1).Add(2)
s2.Add(3).Add(4)
s3 := s1.Union(s2)
gtest.Assert(s3.Contains(1), true)
gtest.Assert(s3.Contains(2), true)
gtest.Assert(s3.Contains(3), true)
gtest.Assert(s3.Contains(4), true)
t.Assert(s3.Contains(1), true)
t.Assert(s3.Contains(2), true)
t.Assert(s3.Contains(3), true)
t.Assert(s3.Contains(4), true)
})
}
func TestIntSet_Diff(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSet()
s2 := gset.NewIntSet()
s1.Add(1).Add(2).Add(3)
s2.Add(3).Add(4).Add(5)
s3 := s1.Diff(s2)
gtest.Assert(s3.Contains(1), true)
gtest.Assert(s3.Contains(2), true)
gtest.Assert(s3.Contains(3), false)
gtest.Assert(s3.Contains(4), false)
t.Assert(s3.Contains(1), true)
t.Assert(s3.Contains(2), true)
t.Assert(s3.Contains(3), false)
t.Assert(s3.Contains(4), false)
})
}
func TestIntSet_Intersect(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSet()
s2 := gset.NewIntSet()
s1.Add(1).Add(2).Add(3)
s2.Add(3).Add(4).Add(5)
s3 := s1.Intersect(s2)
gtest.Assert(s3.Contains(1), false)
gtest.Assert(s3.Contains(2), false)
gtest.Assert(s3.Contains(3), true)
gtest.Assert(s3.Contains(4), false)
t.Assert(s3.Contains(1), false)
t.Assert(s3.Contains(2), false)
t.Assert(s3.Contains(3), true)
t.Assert(s3.Contains(4), false)
})
}
func TestIntSet_Complement(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSet()
s2 := gset.NewIntSet()
s1.Add(1).Add(2).Add(3)
s2.Add(3).Add(4).Add(5)
s3 := s1.Complement(s2)
gtest.Assert(s3.Contains(1), false)
gtest.Assert(s3.Contains(2), false)
gtest.Assert(s3.Contains(4), true)
gtest.Assert(s3.Contains(5), true)
t.Assert(s3.Contains(1), false)
t.Assert(s3.Contains(2), false)
t.Assert(s3.Contains(4), true)
t.Assert(s3.Contains(5), true)
})
}
func TestIntSet_Size(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSet(true)
s1.Add(1).Add(2).Add(3)
gtest.Assert(s1.Size(), 3)
t.Assert(s1.Size(), 3)
})
}
func TestIntSet_Merge(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSet()
s2 := gset.NewIntSet()
s1.Add(1).Add(2).Add(3)
s2.Add(3).Add(4).Add(5)
s3 := s1.Merge(s2)
gtest.Assert(s3.Contains(1), true)
gtest.Assert(s3.Contains(5), true)
gtest.Assert(s3.Contains(6), false)
t.Assert(s3.Contains(1), true)
t.Assert(s3.Contains(5), true)
t.Assert(s3.Contains(6), false)
})
}
func TestIntSet_Join(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSet()
s1.Add(1).Add(2).Add(3)
s3 := s1.Join(",")
gtest.Assert(strings.Contains(s3, "1"), true)
gtest.Assert(strings.Contains(s3, "2"), true)
gtest.Assert(strings.Contains(s3, "3"), true)
t.Assert(strings.Contains(s3, "1"), true)
t.Assert(strings.Contains(s3, "2"), true)
t.Assert(strings.Contains(s3, "3"), true)
})
}
func TestIntSet_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSet()
s1.Add(1).Add(2).Add(3)
s3 := s1.String()
gtest.Assert(strings.Contains(s3, "["), true)
gtest.Assert(strings.Contains(s3, "]"), true)
gtest.Assert(strings.Contains(s3, "1"), true)
gtest.Assert(strings.Contains(s3, "2"), true)
gtest.Assert(strings.Contains(s3, "3"), true)
t.Assert(strings.Contains(s3, "["), true)
t.Assert(strings.Contains(s3, "]"), true)
t.Assert(strings.Contains(s3, "1"), true)
t.Assert(strings.Contains(s3, "2"), true)
t.Assert(strings.Contains(s3, "3"), true)
})
}
func TestIntSet_Sum(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSet()
s1.Add(1).Add(2).Add(3)
s2 := gset.NewIntSet()
s2.Add(5).Add(6).Add(7)
gtest.Assert(s2.Sum(), 18)
t.Assert(s2.Sum(), 18)
})
}
func TestIntSet_Pop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewIntSet()
s.Add(4).Add(2).Add(3)
gtest.Assert(s.Size(), 3)
gtest.AssertIN(s.Pop(), []int{4, 2, 3})
gtest.AssertIN(s.Pop(), []int{4, 2, 3})
gtest.Assert(s.Size(), 1)
t.Assert(s.Size(), 3)
t.AssertIN(s.Pop(), []int{4, 2, 3})
t.AssertIN(s.Pop(), []int{4, 2, 3})
t.Assert(s.Size(), 1)
})
}
func TestIntSet_Pops(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewIntSet()
s.Add(1).Add(4).Add(2).Add(3)
gtest.Assert(s.Size(), 4)
gtest.Assert(s.Pops(0), nil)
gtest.AssertIN(s.Pops(1), []int{1, 4, 2, 3})
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 4)
t.Assert(s.Pops(0), nil)
t.AssertIN(s.Pops(1), []int{1, 4, 2, 3})
t.Assert(s.Size(), 3)
a := s.Pops(2)
gtest.Assert(len(a), 2)
gtest.AssertIN(a, []int{1, 4, 2, 3})
gtest.Assert(s.Size(), 1)
t.Assert(len(a), 2)
t.AssertIN(a, []int{1, 4, 2, 3})
t.Assert(s.Size(), 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewIntSet(true)
a := []int{1, 2, 3, 4}
s.Add(a...)
gtest.Assert(s.Size(), 4)
gtest.Assert(s.Pops(-2), nil)
gtest.AssertIN(s.Pops(-1), a)
t.Assert(s.Size(), 4)
t.Assert(s.Pops(-2), nil)
t.AssertIN(s.Pops(-1), a)
})
}
func TestIntSet_Json(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []int{1, 3, 2, 4}
a1 := gset.NewIntSetFrom(s1)
b1, err1 := json.Marshal(a1)
b2, err2 := json.Marshal(s1)
gtest.Assert(len(b1), len(b2))
gtest.Assert(err1, err2)
t.Assert(len(b1), len(b2))
t.Assert(err1, err2)
a2 := gset.NewIntSet()
err2 = json.Unmarshal(b2, &a2)
gtest.Assert(err2, nil)
gtest.Assert(a2.Contains(1), true)
gtest.Assert(a2.Contains(2), true)
gtest.Assert(a2.Contains(3), true)
gtest.Assert(a2.Contains(4), true)
gtest.Assert(a2.Contains(5), false)
t.Assert(err2, nil)
t.Assert(a2.Contains(1), true)
t.Assert(a2.Contains(2), true)
t.Assert(a2.Contains(3), true)
t.Assert(a2.Contains(4), true)
t.Assert(a2.Contains(5), false)
var a3 gset.IntSet
err := json.Unmarshal(b2, &a3)
gtest.Assert(err, nil)
gtest.Assert(a2.Contains(1), true)
gtest.Assert(a2.Contains(2), true)
gtest.Assert(a2.Contains(3), true)
gtest.Assert(a2.Contains(4), true)
gtest.Assert(a2.Contains(5), false)
t.Assert(err, nil)
t.Assert(a2.Contains(1), true)
t.Assert(a2.Contains(2), true)
t.Assert(a2.Contains(3), true)
t.Assert(a2.Contains(4), true)
t.Assert(a2.Contains(5), false)
})
}
func TestIntSet_AddIfNotExistFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewIntSet(true)
s.Add(1)
gtest.Assert(s.Contains(1), true)
gtest.Assert(s.Contains(2), false)
t.Assert(s.Contains(1), true)
t.Assert(s.Contains(2), false)
s.AddIfNotExistFunc(2, func() int {
return 3
})
gtest.Assert(s.Contains(2), false)
gtest.Assert(s.Contains(3), true)
t.Assert(s.Contains(2), false)
t.Assert(s.Contains(3), true)
s.AddIfNotExistFunc(3, func() int {
return 4
})
gtest.Assert(s.Contains(3), true)
gtest.Assert(s.Contains(4), false)
t.Assert(s.Contains(3), true)
t.Assert(s.Contains(4), false)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewIntSet(true)
s.Add(1)
gtest.Assert(s.Contains(1), true)
gtest.Assert(s.Contains(2), false)
t.Assert(s.Contains(1), true)
t.Assert(s.Contains(2), false)
s.AddIfNotExistFuncLock(2, func() int {
return 3
})
gtest.Assert(s.Contains(2), false)
gtest.Assert(s.Contains(3), true)
t.Assert(s.Contains(2), false)
t.Assert(s.Contains(3), true)
s.AddIfNotExistFuncLock(3, func() int {
return 4
})
gtest.Assert(s.Contains(3), true)
gtest.Assert(s.Contains(4), false)
t.Assert(s.Contains(3), true)
t.Assert(s.Contains(4), false)
})
}
func TestIntSet_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Set *gset.IntSet
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"set": []byte(`[1,2,3]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains(1), true)
gtest.Assert(t.Set.Contains(2), true)
gtest.Assert(t.Set.Contains(3), true)
gtest.Assert(t.Set.Contains(4), false)
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Set.Size(), 3)
t.Assert(v.Set.Contains(1), true)
t.Assert(v.Set.Contains(2), true)
t.Assert(v.Set.Contains(3), true)
t.Assert(v.Set.Contains(4), false)
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"set": g.Slice{1, 2, 3},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains(1), true)
gtest.Assert(t.Set.Contains(2), true)
gtest.Assert(t.Set.Contains(3), true)
gtest.Assert(t.Set.Contains(4), false)
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Set.Size(), 3)
t.Assert(v.Set.Contains(1), true)
t.Assert(v.Set.Contains(2), true)
t.Assert(v.Set.Contains(3), true)
t.Assert(v.Set.Contains(4), false)
})
}

View File

@ -21,30 +21,30 @@ import (
)
func TestStrSet_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewStrSet()
s.Add("1").Add("1").Add("2")
s.Add([]string{"3", "4"}...)
gtest.Assert(s.Size(), 4)
gtest.AssertIN("1", s.Slice())
gtest.AssertIN("2", s.Slice())
gtest.AssertIN("3", s.Slice())
gtest.AssertIN("4", s.Slice())
gtest.AssertNI("0", s.Slice())
gtest.Assert(s.Contains("4"), true)
gtest.Assert(s.Contains("5"), false)
t.Assert(s.Size(), 4)
t.AssertIN("1", s.Slice())
t.AssertIN("2", s.Slice())
t.AssertIN("3", s.Slice())
t.AssertIN("4", s.Slice())
t.AssertNI("0", s.Slice())
t.Assert(s.Contains("4"), true)
t.Assert(s.Contains("5"), false)
s.Remove("1")
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 3)
s.Clear()
gtest.Assert(s.Size(), 0)
t.Assert(s.Size(), 0)
})
}
func TestStrSet_Iterator(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewStrSet()
s.Add("1").Add("2").Add("3")
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 3)
a1 := garray.New(true)
a2 := garray.New(true)
@ -56,22 +56,22 @@ func TestStrSet_Iterator(t *testing.T) {
a2.Append("1")
return true
})
gtest.Assert(a1.Len(), 1)
gtest.Assert(a2.Len(), 3)
t.Assert(a1.Len(), 1)
t.Assert(a2.Len(), 3)
})
}
func TestStrSet_LockFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewStrSet()
s.Add("1").Add("2").Add("3")
gtest.Assert(s.Size(), 3)
t.Assert(s.Size(), 3)
s.LockFunc(func(m map[string]struct{}) {
delete(m, "1")
})
gtest.Assert(s.Size(), 2)
t.Assert(s.Size(), 2)
s.RLockFunc(func(m map[string]struct{}) {
gtest.Assert(m, map[string]struct{}{
t.Assert(m, map[string]struct{}{
"3": struct{}{},
"2": struct{}{},
})
@ -80,322 +80,322 @@ func TestStrSet_LockFunc(t *testing.T) {
}
func TestStrSet_Equal(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSet()
s2 := gset.NewStrSet()
s3 := gset.NewStrSet()
s1.Add("1").Add("2").Add("3")
s2.Add("1").Add("2").Add("3")
s3.Add("1").Add("2").Add("3").Add("4")
gtest.Assert(s1.Equal(s2), true)
gtest.Assert(s1.Equal(s3), false)
t.Assert(s1.Equal(s2), true)
t.Assert(s1.Equal(s3), false)
})
}
func TestStrSet_IsSubsetOf(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSet()
s2 := gset.NewStrSet()
s3 := gset.NewStrSet()
s1.Add("1").Add("2")
s2.Add("1").Add("2").Add("3")
s3.Add("1").Add("2").Add("3").Add("4")
gtest.Assert(s1.IsSubsetOf(s2), true)
gtest.Assert(s2.IsSubsetOf(s3), true)
gtest.Assert(s1.IsSubsetOf(s3), true)
gtest.Assert(s2.IsSubsetOf(s1), false)
gtest.Assert(s3.IsSubsetOf(s2), false)
t.Assert(s1.IsSubsetOf(s2), true)
t.Assert(s2.IsSubsetOf(s3), true)
t.Assert(s1.IsSubsetOf(s3), true)
t.Assert(s2.IsSubsetOf(s1), false)
t.Assert(s3.IsSubsetOf(s2), false)
})
}
func TestStrSet_Union(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSet()
s2 := gset.NewStrSet()
s1.Add("1").Add("2")
s2.Add("3").Add("4")
s3 := s1.Union(s2)
gtest.Assert(s3.Contains("1"), true)
gtest.Assert(s3.Contains("2"), true)
gtest.Assert(s3.Contains("3"), true)
gtest.Assert(s3.Contains("4"), true)
t.Assert(s3.Contains("1"), true)
t.Assert(s3.Contains("2"), true)
t.Assert(s3.Contains("3"), true)
t.Assert(s3.Contains("4"), true)
})
}
func TestStrSet_Diff(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSet()
s2 := gset.NewStrSet()
s1.Add("1").Add("2").Add("3")
s2.Add("3").Add("4").Add("5")
s3 := s1.Diff(s2)
gtest.Assert(s3.Contains("1"), true)
gtest.Assert(s3.Contains("2"), true)
gtest.Assert(s3.Contains("3"), false)
gtest.Assert(s3.Contains("4"), false)
t.Assert(s3.Contains("1"), true)
t.Assert(s3.Contains("2"), true)
t.Assert(s3.Contains("3"), false)
t.Assert(s3.Contains("4"), false)
})
}
func TestStrSet_Intersect(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSet()
s2 := gset.NewStrSet()
s1.Add("1").Add("2").Add("3")
s2.Add("3").Add("4").Add("5")
s3 := s1.Intersect(s2)
gtest.Assert(s3.Contains("1"), false)
gtest.Assert(s3.Contains("2"), false)
gtest.Assert(s3.Contains("3"), true)
gtest.Assert(s3.Contains("4"), false)
t.Assert(s3.Contains("1"), false)
t.Assert(s3.Contains("2"), false)
t.Assert(s3.Contains("3"), true)
t.Assert(s3.Contains("4"), false)
})
}
func TestStrSet_Complement(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSet()
s2 := gset.NewStrSet()
s1.Add("1").Add("2").Add("3")
s2.Add("3").Add("4").Add("5")
s3 := s1.Complement(s2)
gtest.Assert(s3.Contains("1"), false)
gtest.Assert(s3.Contains("2"), false)
gtest.Assert(s3.Contains("4"), true)
gtest.Assert(s3.Contains("5"), true)
t.Assert(s3.Contains("1"), false)
t.Assert(s3.Contains("2"), false)
t.Assert(s3.Contains("4"), true)
t.Assert(s3.Contains("5"), true)
})
}
func TestNewIntSetFrom(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewIntSetFrom([]int{1, 2, 3, 4})
s2 := gset.NewIntSetFrom([]int{5, 6, 7, 8})
gtest.Assert(s1.Contains(3), true)
gtest.Assert(s1.Contains(5), false)
gtest.Assert(s2.Contains(3), false)
gtest.Assert(s2.Contains(5), true)
t.Assert(s1.Contains(3), true)
t.Assert(s1.Contains(5), false)
t.Assert(s2.Contains(3), false)
t.Assert(s2.Contains(5), true)
})
}
func TestStrSet_Merge(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSet()
s2 := gset.NewStrSet()
s1.Add("1").Add("2").Add("3")
s2.Add("3").Add("4").Add("5")
s3 := s1.Merge(s2)
gtest.Assert(s3.Contains("1"), true)
gtest.Assert(s3.Contains("6"), false)
gtest.Assert(s3.Contains("4"), true)
gtest.Assert(s3.Contains("5"), true)
t.Assert(s3.Contains("1"), true)
t.Assert(s3.Contains("6"), false)
t.Assert(s3.Contains("4"), true)
t.Assert(s3.Contains("5"), true)
})
}
func TestNewStrSetFrom(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
gtest.Assert(s1.Contains("b"), true)
gtest.Assert(s1.Contains("d"), false)
t.Assert(s1.Contains("b"), true)
t.Assert(s1.Contains("d"), false)
})
}
func TestStrSet_Join(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
str1 := s1.Join(",")
gtest.Assert(strings.Contains(str1, "b"), true)
gtest.Assert(strings.Contains(str1, "d"), false)
t.Assert(strings.Contains(str1, "b"), true)
t.Assert(strings.Contains(str1, "d"), false)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSet()
s1.Add("a").Add(`"b"`).Add(`\c`)
str1 := s1.Join(",")
gtest.Assert(strings.Contains(str1, `"b"`), true)
gtest.Assert(strings.Contains(str1, `\c`), true)
gtest.Assert(strings.Contains(str1, `a`), true)
t.Assert(strings.Contains(str1, `"b"`), true)
t.Assert(strings.Contains(str1, `\c`), true)
t.Assert(strings.Contains(str1, `a`), true)
})
}
func TestStrSet_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
str1 := s1.String()
gtest.Assert(strings.Contains(str1, "b"), true)
gtest.Assert(strings.Contains(str1, "d"), false)
t.Assert(strings.Contains(str1, "b"), true)
t.Assert(strings.Contains(str1, "d"), false)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.New(true)
s1.Add("a").Add("a2").Add("b").Add("c")
str1 := s1.String()
gtest.Assert(strings.Contains(str1, "["), true)
gtest.Assert(strings.Contains(str1, "]"), true)
gtest.Assert(strings.Contains(str1, "a2"), true)
t.Assert(strings.Contains(str1, "["), true)
t.Assert(strings.Contains(str1, "]"), true)
t.Assert(strings.Contains(str1, "a2"), true)
})
}
func TestStrSet_Sum(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
s2 := gset.NewIntSetFrom([]int{2, 3, 4}, true)
gtest.Assert(s1.Sum(), 0)
gtest.Assert(s2.Sum(), 9)
t.Assert(s1.Sum(), 0)
t.Assert(s2.Sum(), 9)
})
}
func TestStrSet_Size(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
gtest.Assert(s1.Size(), 3)
t.Assert(s1.Size(), 3)
})
}
func TestStrSet_Remove(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
s1 = s1.Remove("b")
gtest.Assert(s1.Contains("b"), false)
gtest.Assert(s1.Contains("c"), true)
t.Assert(s1.Contains("b"), false)
t.Assert(s1.Contains("c"), true)
})
}
func TestStrSet_Pop(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a := []string{"a", "b", "c", "d"}
s := gset.NewStrSetFrom(a, true)
gtest.Assert(s.Size(), 4)
gtest.AssertIN(s.Pop(), a)
gtest.Assert(s.Size(), 3)
gtest.AssertIN(s.Pop(), a)
gtest.Assert(s.Size(), 2)
t.Assert(s.Size(), 4)
t.AssertIN(s.Pop(), a)
t.Assert(s.Size(), 3)
t.AssertIN(s.Pop(), a)
t.Assert(s.Size(), 2)
})
}
func TestStrSet_Pops(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
a := []string{"a", "b", "c", "d"}
s := gset.NewStrSetFrom(a, true)
array := s.Pops(2)
gtest.Assert(len(array), 2)
gtest.Assert(s.Size(), 2)
gtest.AssertIN(array, a)
gtest.Assert(s.Pops(0), nil)
gtest.AssertIN(s.Pops(2), a)
gtest.Assert(s.Size(), 0)
t.Assert(len(array), 2)
t.Assert(s.Size(), 2)
t.AssertIN(array, a)
t.Assert(s.Pops(0), nil)
t.AssertIN(s.Pops(2), a)
t.Assert(s.Size(), 0)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewStrSet(true)
a := []string{"1", "2", "3", "4"}
s.Add(a...)
gtest.Assert(s.Size(), 4)
gtest.Assert(s.Pops(-2), nil)
gtest.AssertIN(s.Pops(-1), a)
t.Assert(s.Size(), 4)
t.Assert(s.Pops(-2), nil)
t.AssertIN(s.Pops(-1), a)
})
}
func TestStrSet_Json(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s1 := []string{"a", "b", "d", "c"}
a1 := gset.NewStrSetFrom(s1)
b1, err1 := json.Marshal(a1)
b2, err2 := json.Marshal(s1)
gtest.Assert(len(b1), len(b2))
gtest.Assert(err1, err2)
t.Assert(len(b1), len(b2))
t.Assert(err1, err2)
a2 := gset.NewStrSet()
err2 = json.Unmarshal(b2, &a2)
gtest.Assert(err2, nil)
gtest.Assert(a2.Contains("a"), true)
gtest.Assert(a2.Contains("b"), true)
gtest.Assert(a2.Contains("c"), true)
gtest.Assert(a2.Contains("d"), true)
gtest.Assert(a2.Contains("e"), false)
t.Assert(err2, nil)
t.Assert(a2.Contains("a"), true)
t.Assert(a2.Contains("b"), true)
t.Assert(a2.Contains("c"), true)
t.Assert(a2.Contains("d"), true)
t.Assert(a2.Contains("e"), false)
var a3 gset.StrSet
err := json.Unmarshal(b2, &a3)
gtest.Assert(err, nil)
gtest.Assert(a3.Contains("a"), true)
gtest.Assert(a3.Contains("b"), true)
gtest.Assert(a3.Contains("c"), true)
gtest.Assert(a3.Contains("d"), true)
gtest.Assert(a3.Contains("e"), false)
t.Assert(err, nil)
t.Assert(a3.Contains("a"), true)
t.Assert(a3.Contains("b"), true)
t.Assert(a3.Contains("c"), true)
t.Assert(a3.Contains("d"), true)
t.Assert(a3.Contains("e"), false)
})
}
func TestStrSet_AddIfNotExistFunc(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewStrSet(true)
s.Add("1")
gtest.Assert(s.Contains("1"), true)
gtest.Assert(s.Contains("2"), false)
t.Assert(s.Contains("1"), true)
t.Assert(s.Contains("2"), false)
s.AddIfNotExistFunc("2", func() string {
return "3"
})
gtest.Assert(s.Contains("2"), false)
gtest.Assert(s.Contains("3"), true)
t.Assert(s.Contains("2"), false)
t.Assert(s.Contains("3"), true)
s.AddIfNotExistFunc("3", func() string {
return "4"
})
gtest.Assert(s.Contains("3"), true)
gtest.Assert(s.Contains("4"), false)
t.Assert(s.Contains("3"), true)
t.Assert(s.Contains("4"), false)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := gset.NewStrSet(true)
s.Add("1")
gtest.Assert(s.Contains("1"), true)
gtest.Assert(s.Contains("2"), false)
t.Assert(s.Contains("1"), true)
t.Assert(s.Contains("2"), false)
s.AddIfNotExistFuncLock("2", func() string {
return "3"
})
gtest.Assert(s.Contains("2"), false)
gtest.Assert(s.Contains("3"), true)
t.Assert(s.Contains("2"), false)
t.Assert(s.Contains("3"), true)
s.AddIfNotExistFuncLock("3", func() string {
return "4"
})
gtest.Assert(s.Contains("3"), true)
gtest.Assert(s.Contains("4"), false)
t.Assert(s.Contains("3"), true)
t.Assert(s.Contains("4"), false)
})
}
func TestStrSet_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Set *gset.StrSet
}
// JSON
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"set": []byte(`["1","2","3"]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains("1"), true)
gtest.Assert(t.Set.Contains("2"), true)
gtest.Assert(t.Set.Contains("3"), true)
gtest.Assert(t.Set.Contains("4"), false)
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Set.Size(), 3)
t.Assert(v.Set.Contains("1"), true)
t.Assert(v.Set.Contains("2"), true)
t.Assert(v.Set.Contains("3"), true)
t.Assert(v.Set.Contains("4"), false)
})
// Map
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(g.Map{
"name": "john",
"set": g.SliceStr{"1", "2", "3"},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains("1"), true)
gtest.Assert(t.Set.Contains("2"), true)
gtest.Assert(t.Set.Contains("3"), true)
gtest.Assert(t.Set.Contains("4"), false)
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Set.Size(), 3)
t.Assert(v.Set.Contains("1"), true)
t.Assert(v.Set.Contains("2"), true)
t.Assert(v.Set.Contains("3"), true)
t.Assert(v.Set.Contains("4"), false)
})
}

View File

@ -17,96 +17,99 @@ import (
)
func Test_AVLTree_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewAVLTree(gutil.ComparatorString)
m.Set("key1", "val1")
gtest.Assert(m.Keys(), []interface{}{"key1"})
t.Assert(m.Keys(), []interface{}{"key1"})
gtest.Assert(m.Get("key1"), "val1")
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get("key1"), "val1")
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet("key2", "val2"), "val2")
gtest.Assert(m.GetOrSet("key2", "val2"), "val2")
gtest.Assert(m.SetIfNotExist("key2", "val2"), false)
t.Assert(m.GetOrSet("key2", "val2"), "val2")
t.Assert(m.GetOrSet("key2", "val2"), "val2")
t.Assert(m.SetIfNotExist("key2", "val2"), false)
gtest.Assert(m.SetIfNotExist("key3", "val3"), true)
t.Assert(m.SetIfNotExist("key3", "val3"), true)
gtest.Assert(m.Remove("key2"), "val2")
gtest.Assert(m.Contains("key2"), false)
t.Assert(m.Remove("key2"), "val2")
t.Assert(m.Contains("key2"), false)
gtest.AssertIN("key3", m.Keys())
gtest.AssertIN("key1", m.Keys())
gtest.AssertIN("val3", m.Values())
gtest.AssertIN("val1", m.Values())
t.AssertIN("key3", m.Keys())
t.AssertIN("key1", m.Keys())
t.AssertIN("val3", m.Values())
t.AssertIN("val1", m.Values())
m.Sets(map[interface{}]interface{}{"key3": "val3", "key1": "val1"})
m.Flip()
gtest.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val1": "key1"})
t.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val1": "key1"})
m.Flip(gutil.ComparatorString)
gtest.Assert(m.Map(), map[interface{}]interface{}{"key3": "val3", "key1": "val1"})
t.Assert(m.Map(), map[interface{}]interface{}{"key3": "val3", "key1": "val1"})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gtree.NewAVLTreeFrom(gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
t.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
})
}
func Test_AVLTree_Set_Fun(t *testing.T) {
//GetOrSetFunc lock or unlock
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewAVLTree(gutil.ComparatorString)
gtest.Assert(m.GetOrSetFunc("fun", getValue), 3)
gtest.Assert(m.GetOrSetFunc("fun", getValue), 3)
gtest.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
gtest.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
gtest.Assert(m.Get("funlock"), 3)
gtest.Assert(m.Get("fun"), 3)
t.Assert(m.GetOrSetFunc("fun", getValue), 3)
t.Assert(m.GetOrSetFunc("fun", getValue), 3)
t.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
t.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
t.Assert(m.Get("funlock"), 3)
t.Assert(m.Get("fun"), 3)
})
//SetIfNotExistFunc lock or unlock
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewAVLTree(gutil.ComparatorString)
gtest.Assert(m.SetIfNotExistFunc("fun", getValue), true)
gtest.Assert(m.SetIfNotExistFunc("fun", getValue), false)
gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), true)
gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
gtest.Assert(m.Get("funlock"), 3)
gtest.Assert(m.Get("fun"), 3)
t.Assert(m.SetIfNotExistFunc("fun", getValue), true)
t.Assert(m.SetIfNotExistFunc("fun", getValue), false)
t.Assert(m.SetIfNotExistFuncLock("funlock", getValue), true)
t.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
t.Assert(m.Get("funlock"), 3)
t.Assert(m.Get("fun"), 3)
})
}
func Test_AVLTree_Get_Set_Var(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewAVLTree(gutil.ComparatorString)
gtest.AssertEQ(m.SetIfNotExist("key1", "val1"), true)
gtest.AssertEQ(m.SetIfNotExist("key1", "val1"), false)
gtest.AssertEQ(m.GetVarOrSet("key1", "val1"), gvar.New("val1", true))
gtest.AssertEQ(m.GetVar("key1"), gvar.New("val1", true))
t.AssertEQ(m.SetIfNotExist("key1", "val1"), true)
t.AssertEQ(m.SetIfNotExist("key1", "val1"), false)
t.AssertEQ(m.GetVarOrSet("key1", "val1"), gvar.New("val1", true))
t.AssertEQ(m.GetVar("key1"), gvar.New("val1", true))
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewAVLTree(gutil.ComparatorString)
gtest.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
gtest.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
gtest.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
gtest.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
})
}
func Test_AVLTree_Batch(t *testing.T) {
m := gtree.NewAVLTree(gutil.ComparatorString)
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
gtest.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
gtest.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
gtest.C(t, func(t *gtest.T) {
m := gtree.NewAVLTree(gutil.ComparatorString)
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
t.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
t.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
})
}
func Test_AVLTree_Iterator(t *testing.T) {
keys := []string{"1", "key1", "key2", "key3", "key4"}
keyLen := len(keys)
index := 0
@ -114,23 +117,26 @@ func Test_AVLTree_Iterator(t *testing.T) {
expect := map[interface{}]interface{}{"key4": "val4", 1: 1, "key1": "val1", "key2": "val2", "key3": "val3"}
m := gtree.NewAVLTreeFrom(gutil.ComparatorString, expect)
m.Iterator(func(k interface{}, v interface{}) bool {
gtest.Assert(k, keys[index])
index++
gtest.Assert(expect[k], v)
return true
})
m.IteratorDesc(func(k interface{}, v interface{}) bool {
index--
gtest.Assert(k, keys[index])
gtest.Assert(expect[k], v)
return true
gtest.C(t, func(t *gtest.T) {
m.Iterator(func(k interface{}, v interface{}) bool {
t.Assert(k, keys[index])
index++
t.Assert(expect[k], v)
return true
})
m.IteratorDesc(func(k interface{}, v interface{}) bool {
index--
t.Assert(k, keys[index])
t.Assert(expect[k], v)
return true
})
})
m.Print()
// 断言返回值对遍历控制
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := 0
j := 0
m.Iterator(func(k interface{}, v interface{}) bool {
@ -141,11 +147,11 @@ func Test_AVLTree_Iterator(t *testing.T) {
j++
return false
})
gtest.Assert(i, keyLen)
gtest.Assert(j, 1)
t.Assert(i, keyLen)
t.Assert(j, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := 0
j := 0
m.IteratorDesc(func(k interface{}, v interface{}) bool {
@ -156,8 +162,8 @@ func Test_AVLTree_Iterator(t *testing.T) {
j++
return false
})
gtest.Assert(i, keyLen)
gtest.Assert(j, 1)
t.Assert(i, keyLen)
t.Assert(j, 1)
})
}
@ -169,27 +175,27 @@ func Test_AVLTree_IteratorFrom(t *testing.T) {
}
tree := gtree.NewAVLTreeFrom(gutil.ComparatorInt, m)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
n := 5
tree.IteratorFrom(5, true, func(key, value interface{}) bool {
gtest.Assert(n, key)
gtest.Assert(n*10, value)
t.Assert(n, key)
t.Assert(n*10, value)
n++
return true
})
i := 5
tree.IteratorAscFrom(5, true, func(key, value interface{}) bool {
gtest.Assert(i, key)
gtest.Assert(i*10, value)
t.Assert(i, key)
t.Assert(i*10, value)
i++
return true
})
j := 5
tree.IteratorDescFrom(5, true, func(key, value interface{}) bool {
gtest.Assert(j, key)
gtest.Assert(j*10, value)
t.Assert(j, key)
t.Assert(j*10, value)
j--
return true
})
@ -197,31 +203,33 @@ func Test_AVLTree_IteratorFrom(t *testing.T) {
}
func Test_AVLTree_Clone(t *testing.T) {
//clone 方法是深克隆
m := gtree.NewAVLTreeFrom(gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
gtest.AssertIN(1, m_clone.Keys())
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gtree.NewAVLTreeFrom(gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
t.AssertIN(1, m_clone.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
gtest.AssertIN("key1", m.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
t.AssertIN("key1", m.Keys())
})
}
func Test_AVLTree_LRNode(t *testing.T) {
expect := map[interface{}]interface{}{"key4": "val4", "key1": "val1", "key2": "val2", "key3": "val3"}
//safe
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewAVLTreeFrom(gutil.ComparatorString, expect)
gtest.Assert(m.Left().Key, "key1")
gtest.Assert(m.Right().Key, "key4")
t.Assert(m.Left().Key, "key1")
t.Assert(m.Right().Key, "key4")
})
//unsafe
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewAVLTreeFrom(gutil.ComparatorString, expect, true)
gtest.Assert(m.Left().Key, "key1")
gtest.Assert(m.Right().Key, "key4")
t.Assert(m.Left().Key, "key1")
t.Assert(m.Right().Key, "key4")
})
}
@ -237,34 +245,34 @@ func Test_AVLTree_CeilingFloor(t *testing.T) {
8: "val8",
4: "val4"}
//found and eq
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewAVLTreeFrom(gutil.ComparatorInt, expect)
c, cf := m.Ceiling(8)
gtest.Assert(cf, true)
gtest.Assert(c.Value, "val8")
t.Assert(cf, true)
t.Assert(c.Value, "val8")
f, ff := m.Floor(20)
gtest.Assert(ff, true)
gtest.Assert(f.Value, "val20")
t.Assert(ff, true)
t.Assert(f.Value, "val20")
})
//found and neq
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewAVLTreeFrom(gutil.ComparatorInt, expect)
c, cf := m.Ceiling(9)
gtest.Assert(cf, true)
gtest.Assert(c.Value, "val10")
t.Assert(cf, true)
t.Assert(c.Value, "val10")
f, ff := m.Floor(5)
gtest.Assert(ff, true)
gtest.Assert(f.Value, "val4")
t.Assert(ff, true)
t.Assert(f.Value, "val4")
})
//nofound
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewAVLTreeFrom(gutil.ComparatorInt, expect)
c, cf := m.Ceiling(21)
gtest.Assert(cf, false)
gtest.Assert(c, nil)
t.Assert(cf, false)
t.Assert(c, nil)
f, ff := m.Floor(-1)
gtest.Assert(ff, false)
gtest.Assert(f, nil)
t.Assert(ff, false)
t.Assert(f, nil)
})
}
@ -274,11 +282,11 @@ func Test_AVLTree_Remove(t *testing.T) {
m.Set(i, fmt.Sprintf("val%d", i))
}
expect := m.Map()
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
for k, v := range expect {
m1 := m.Clone()
gtest.Assert(m1.Remove(k), v)
gtest.Assert(m1.Remove(k), nil)
t.Assert(m1.Remove(k), v)
t.Assert(m1.Remove(k), nil)
}
})
}

View File

@ -17,88 +17,90 @@ import (
)
func Test_BTree_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewBTree(3, gutil.ComparatorString)
m.Set("key1", "val1")
gtest.Assert(m.Height(), 1)
t.Assert(m.Height(), 1)
gtest.Assert(m.Keys(), []interface{}{"key1"})
t.Assert(m.Keys(), []interface{}{"key1"})
gtest.Assert(m.Get("key1"), "val1")
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get("key1"), "val1")
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet("key2", "val2"), "val2")
gtest.Assert(m.SetIfNotExist("key2", "val2"), false)
t.Assert(m.GetOrSet("key2", "val2"), "val2")
t.Assert(m.SetIfNotExist("key2", "val2"), false)
gtest.Assert(m.SetIfNotExist("key3", "val3"), true)
t.Assert(m.SetIfNotExist("key3", "val3"), true)
gtest.Assert(m.Remove("key2"), "val2")
gtest.Assert(m.Contains("key2"), false)
t.Assert(m.Remove("key2"), "val2")
t.Assert(m.Contains("key2"), false)
gtest.AssertIN("key3", m.Keys())
gtest.AssertIN("key1", m.Keys())
gtest.AssertIN("val3", m.Values())
gtest.AssertIN("val1", m.Values())
t.AssertIN("key3", m.Keys())
t.AssertIN("key1", m.Keys())
t.AssertIN("val3", m.Values())
t.AssertIN("val1", m.Values())
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gtree.NewBTreeFrom(3, gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
t.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
})
}
func Test_BTree_Set_Fun(t *testing.T) {
//GetOrSetFunc lock or unlock
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewBTree(3, gutil.ComparatorString)
gtest.Assert(m.GetOrSetFunc("fun", getValue), 3)
gtest.Assert(m.GetOrSetFunc("fun", getValue), 3)
gtest.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
gtest.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
gtest.Assert(m.Get("funlock"), 3)
gtest.Assert(m.Get("fun"), 3)
t.Assert(m.GetOrSetFunc("fun", getValue), 3)
t.Assert(m.GetOrSetFunc("fun", getValue), 3)
t.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
t.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
t.Assert(m.Get("funlock"), 3)
t.Assert(m.Get("fun"), 3)
})
//SetIfNotExistFunc lock or unlock
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewBTree(3, gutil.ComparatorString)
gtest.Assert(m.SetIfNotExistFunc("fun", getValue), true)
gtest.Assert(m.SetIfNotExistFunc("fun", getValue), false)
gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), true)
gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
gtest.Assert(m.Get("funlock"), 3)
gtest.Assert(m.Get("fun"), 3)
t.Assert(m.SetIfNotExistFunc("fun", getValue), true)
t.Assert(m.SetIfNotExistFunc("fun", getValue), false)
t.Assert(m.SetIfNotExistFuncLock("funlock", getValue), true)
t.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
t.Assert(m.Get("funlock"), 3)
t.Assert(m.Get("fun"), 3)
})
}
func Test_BTree_Get_Set_Var(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewBTree(3, gutil.ComparatorString)
gtest.AssertEQ(m.SetIfNotExist("key1", "val1"), true)
gtest.AssertEQ(m.SetIfNotExist("key1", "val1"), false)
gtest.AssertEQ(m.GetVarOrSet("key1", "val1"), gvar.New("val1", true))
gtest.AssertEQ(m.GetVar("key1"), gvar.New("val1", true))
t.AssertEQ(m.SetIfNotExist("key1", "val1"), true)
t.AssertEQ(m.SetIfNotExist("key1", "val1"), false)
t.AssertEQ(m.GetVarOrSet("key1", "val1"), gvar.New("val1", true))
t.AssertEQ(m.GetVar("key1"), gvar.New("val1", true))
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewBTree(3, gutil.ComparatorString)
gtest.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
gtest.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
gtest.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
gtest.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
})
}
func Test_BTree_Batch(t *testing.T) {
m := gtree.NewBTree(3, gutil.ComparatorString)
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
gtest.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
gtest.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
gtest.C(t, func(t *gtest.T) {
m := gtree.NewBTree(3, gutil.ComparatorString)
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
t.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
t.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
})
}
func Test_BTree_Iterator(t *testing.T) {
@ -109,23 +111,26 @@ func Test_BTree_Iterator(t *testing.T) {
expect := map[interface{}]interface{}{"key4": "val4", 1: 1, "key1": "val1", "key2": "val2", "key3": "val3"}
m := gtree.NewBTreeFrom(3, gutil.ComparatorString, expect)
m.Iterator(func(k interface{}, v interface{}) bool {
gtest.Assert(k, keys[index])
index++
gtest.Assert(expect[k], v)
return true
})
m.IteratorDesc(func(k interface{}, v interface{}) bool {
index--
gtest.Assert(k, keys[index])
gtest.Assert(expect[k], v)
return true
gtest.C(t, func(t *gtest.T) {
m.Iterator(func(k interface{}, v interface{}) bool {
t.Assert(k, keys[index])
index++
t.Assert(expect[k], v)
return true
})
m.IteratorDesc(func(k interface{}, v interface{}) bool {
index--
t.Assert(k, keys[index])
t.Assert(expect[k], v)
return true
})
})
m.Print()
// 断言返回值对遍历控制
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := 0
j := 0
m.Iterator(func(k interface{}, v interface{}) bool {
@ -136,11 +141,11 @@ func Test_BTree_Iterator(t *testing.T) {
j++
return false
})
gtest.Assert(i, keyLen)
gtest.Assert(j, 1)
t.Assert(i, keyLen)
t.Assert(j, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := 0
j := 0
m.IteratorDesc(func(k interface{}, v interface{}) bool {
@ -151,8 +156,8 @@ func Test_BTree_Iterator(t *testing.T) {
j++
return false
})
gtest.Assert(i, keyLen)
gtest.Assert(j, 1)
t.Assert(i, keyLen)
t.Assert(j, 1)
})
}
@ -163,27 +168,27 @@ func Test_BTree_IteratorFrom(t *testing.T) {
}
tree := gtree.NewBTreeFrom(3, gutil.ComparatorInt, m)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
n := 5
tree.IteratorFrom(5, true, func(key, value interface{}) bool {
gtest.Assert(n, key)
gtest.Assert(n*10, value)
t.Assert(n, key)
t.Assert(n*10, value)
n++
return true
})
i := 5
tree.IteratorAscFrom(5, true, func(key, value interface{}) bool {
gtest.Assert(i, key)
gtest.Assert(i*10, value)
t.Assert(i, key)
t.Assert(i*10, value)
i++
return true
})
j := 5
tree.IteratorDescFrom(5, true, func(key, value interface{}) bool {
gtest.Assert(j, key)
gtest.Assert(j*10, value)
t.Assert(j, key)
t.Assert(j*10, value)
j--
return true
})
@ -191,31 +196,33 @@ func Test_BTree_IteratorFrom(t *testing.T) {
}
func Test_BTree_Clone(t *testing.T) {
//clone 方法是深克隆
m := gtree.NewBTreeFrom(3, gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
gtest.AssertIN(1, m_clone.Keys())
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gtree.NewBTreeFrom(3, gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
t.AssertIN(1, m_clone.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
gtest.AssertIN("key1", m.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
t.AssertIN("key1", m.Keys())
})
}
func Test_BTree_LRNode(t *testing.T) {
expect := map[interface{}]interface{}{"key4": "val4", "key1": "val1", "key2": "val2", "key3": "val3"}
//safe
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewBTreeFrom(3, gutil.ComparatorString, expect)
gtest.Assert(m.Left().Key, "key1")
gtest.Assert(m.Right().Key, "key4")
t.Assert(m.Left().Key, "key1")
t.Assert(m.Right().Key, "key4")
})
//unsafe
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewBTreeFrom(3, gutil.ComparatorString, expect, true)
gtest.Assert(m.Left().Key, "key1")
gtest.Assert(m.Right().Key, "key4")
t.Assert(m.Left().Key, "key1")
t.Assert(m.Right().Key, "key4")
})
}
@ -225,11 +232,11 @@ func Test_BTree_Remove(t *testing.T) {
m.Set(i, fmt.Sprintf("val%d", i))
}
expect := m.Map()
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
for k, v := range expect {
m1 := m.Clone()
gtest.Assert(m1.Remove(k), v)
gtest.Assert(m1.Remove(k), nil)
t.Assert(m1.Remove(k), v)
t.Assert(m1.Remove(k), nil)
}
})
}

View File

@ -21,94 +21,96 @@ func getValue() interface{} {
}
func Test_RedBlackTree_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewRedBlackTree(gutil.ComparatorString)
m.Set("key1", "val1")
gtest.Assert(m.Keys(), []interface{}{"key1"})
t.Assert(m.Keys(), []interface{}{"key1"})
gtest.Assert(m.Get("key1"), "val1")
gtest.Assert(m.Size(), 1)
gtest.Assert(m.IsEmpty(), false)
t.Assert(m.Get("key1"), "val1")
t.Assert(m.Size(), 1)
t.Assert(m.IsEmpty(), false)
gtest.Assert(m.GetOrSet("key2", "val2"), "val2")
gtest.Assert(m.GetOrSet("key2", "val2"), "val2")
gtest.Assert(m.SetIfNotExist("key2", "val2"), false)
t.Assert(m.GetOrSet("key2", "val2"), "val2")
t.Assert(m.GetOrSet("key2", "val2"), "val2")
t.Assert(m.SetIfNotExist("key2", "val2"), false)
gtest.Assert(m.SetIfNotExist("key3", "val3"), true)
t.Assert(m.SetIfNotExist("key3", "val3"), true)
gtest.Assert(m.Remove("key2"), "val2")
gtest.Assert(m.Contains("key2"), false)
t.Assert(m.Remove("key2"), "val2")
t.Assert(m.Contains("key2"), false)
gtest.AssertIN("key3", m.Keys())
gtest.AssertIN("key1", m.Keys())
gtest.AssertIN("val3", m.Values())
gtest.AssertIN("val1", m.Values())
t.AssertIN("key3", m.Keys())
t.AssertIN("key1", m.Keys())
t.AssertIN("val3", m.Values())
t.AssertIN("val1", m.Values())
m.Sets(map[interface{}]interface{}{"key3": "val3", "key1": "val1"})
m.Flip()
gtest.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val1": "key1"})
t.Assert(m.Map(), map[interface{}]interface{}{"val3": "key3", "val1": "key1"})
m.Flip(gutil.ComparatorString)
gtest.Assert(m.Map(), map[interface{}]interface{}{"key3": "val3", "key1": "val1"})
t.Assert(m.Map(), map[interface{}]interface{}{"key3": "val3", "key1": "val1"})
m.Clear()
gtest.Assert(m.Size(), 0)
gtest.Assert(m.IsEmpty(), true)
t.Assert(m.Size(), 0)
t.Assert(m.IsEmpty(), true)
m2 := gtree.NewRedBlackTreeFrom(gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
t.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
})
}
func Test_RedBlackTree_Set_Fun(t *testing.T) {
//GetOrSetFunc lock or unlock
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewRedBlackTree(gutil.ComparatorString)
gtest.Assert(m.GetOrSetFunc("fun", getValue), 3)
gtest.Assert(m.GetOrSetFunc("fun", getValue), 3)
gtest.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
gtest.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
gtest.Assert(m.Get("funlock"), 3)
gtest.Assert(m.Get("fun"), 3)
t.Assert(m.GetOrSetFunc("fun", getValue), 3)
t.Assert(m.GetOrSetFunc("fun", getValue), 3)
t.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
t.Assert(m.GetOrSetFuncLock("funlock", getValue), 3)
t.Assert(m.Get("funlock"), 3)
t.Assert(m.Get("fun"), 3)
})
//SetIfNotExistFunc lock or unlock
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewRedBlackTree(gutil.ComparatorString)
gtest.Assert(m.SetIfNotExistFunc("fun", getValue), true)
gtest.Assert(m.SetIfNotExistFunc("fun", getValue), false)
gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), true)
gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
gtest.Assert(m.Get("funlock"), 3)
gtest.Assert(m.Get("fun"), 3)
t.Assert(m.SetIfNotExistFunc("fun", getValue), true)
t.Assert(m.SetIfNotExistFunc("fun", getValue), false)
t.Assert(m.SetIfNotExistFuncLock("funlock", getValue), true)
t.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
t.Assert(m.Get("funlock"), 3)
t.Assert(m.Get("fun"), 3)
})
}
func Test_RedBlackTree_Get_Set_Var(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewRedBlackTree(gutil.ComparatorString)
gtest.AssertEQ(m.SetIfNotExist("key1", "val1"), true)
gtest.AssertEQ(m.SetIfNotExist("key1", "val1"), false)
gtest.AssertEQ(m.GetVarOrSet("key1", "val1"), gvar.New("val1", true))
gtest.AssertEQ(m.GetVar("key1"), gvar.New("val1", true))
t.AssertEQ(m.SetIfNotExist("key1", "val1"), true)
t.AssertEQ(m.SetIfNotExist("key1", "val1"), false)
t.AssertEQ(m.GetVarOrSet("key1", "val1"), gvar.New("val1", true))
t.AssertEQ(m.GetVar("key1"), gvar.New("val1", true))
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewRedBlackTree(gutil.ComparatorString)
gtest.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
gtest.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
gtest.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
gtest.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFunc("fun", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
t.AssertEQ(m.GetVarOrSetFuncLock("funlock", getValue), gvar.New(3, true))
})
}
func Test_RedBlackTree_Batch(t *testing.T) {
m := gtree.NewRedBlackTree(gutil.ComparatorString)
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
gtest.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
gtest.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
gtest.C(t, func(t *gtest.T) {
m := gtree.NewRedBlackTree(gutil.ComparatorString)
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
t.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
t.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
})
}
func Test_RedBlackTree_Iterator(t *testing.T) {
@ -117,25 +119,27 @@ func Test_RedBlackTree_Iterator(t *testing.T) {
index := 0
expect := map[interface{}]interface{}{"key4": "val4", 1: 1, "key1": "val1", "key2": "val2", "key3": "val3"}
m := gtree.NewRedBlackTreeFrom(gutil.ComparatorString, expect)
m.Iterator(func(k interface{}, v interface{}) bool {
gtest.Assert(k, keys[index])
index++
gtest.Assert(expect[k], v)
return true
})
m.IteratorDesc(func(k interface{}, v interface{}) bool {
index--
gtest.Assert(k, keys[index])
gtest.Assert(expect[k], v)
return true
})
gtest.C(t, func(t *gtest.T) {
m.Iterator(func(k interface{}, v interface{}) bool {
t.Assert(k, keys[index])
index++
t.Assert(expect[k], v)
return true
})
m.IteratorDesc(func(k interface{}, v interface{}) bool {
index--
t.Assert(k, keys[index])
t.Assert(expect[k], v)
return true
})
})
m.Print()
// 断言返回值对遍历控制
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := 0
j := 0
m.Iterator(func(k interface{}, v interface{}) bool {
@ -146,11 +150,11 @@ func Test_RedBlackTree_Iterator(t *testing.T) {
j++
return false
})
gtest.Assert(i, keyLen)
gtest.Assert(j, 1)
t.Assert(i, keyLen)
t.Assert(j, 1)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := 0
j := 0
m.IteratorDesc(func(k interface{}, v interface{}) bool {
@ -161,8 +165,8 @@ func Test_RedBlackTree_Iterator(t *testing.T) {
j++
return false
})
gtest.Assert(i, keyLen)
gtest.Assert(j, 1)
t.Assert(i, keyLen)
t.Assert(j, 1)
})
}
@ -173,27 +177,27 @@ func Test_RedBlackTree_IteratorFrom(t *testing.T) {
}
tree := gtree.NewRedBlackTreeFrom(gutil.ComparatorInt, m)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
n := 5
tree.IteratorFrom(5, true, func(key, value interface{}) bool {
gtest.Assert(n, key)
gtest.Assert(n*10, value)
t.Assert(n, key)
t.Assert(n*10, value)
n++
return true
})
i := 5
tree.IteratorAscFrom(5, true, func(key, value interface{}) bool {
gtest.Assert(i, key)
gtest.Assert(i*10, value)
t.Assert(i, key)
t.Assert(i*10, value)
i++
return true
})
j := 5
tree.IteratorDescFrom(5, true, func(key, value interface{}) bool {
gtest.Assert(j, key)
gtest.Assert(j*10, value)
t.Assert(j, key)
t.Assert(j*10, value)
j--
return true
})
@ -201,31 +205,33 @@ func Test_RedBlackTree_IteratorFrom(t *testing.T) {
}
func Test_RedBlackTree_Clone(t *testing.T) {
//clone 方法是深克隆
m := gtree.NewRedBlackTreeFrom(gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
gtest.AssertIN(1, m_clone.Keys())
gtest.C(t, func(t *gtest.T) {
//clone 方法是深克隆
m := gtree.NewRedBlackTreeFrom(gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
m.Remove(1)
//修改原 map,clone 后的 map 不影响
t.AssertIN(1, m_clone.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
gtest.AssertIN("key1", m.Keys())
m_clone.Remove("key1")
//修改clone map,原 map 不影响
t.AssertIN("key1", m.Keys())
})
}
func Test_RedBlackTree_LRNode(t *testing.T) {
expect := map[interface{}]interface{}{"key4": "val4", "key1": "val1", "key2": "val2", "key3": "val3"}
//safe
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewRedBlackTreeFrom(gutil.ComparatorString, expect)
gtest.Assert(m.Left().Key, "key1")
gtest.Assert(m.Right().Key, "key4")
t.Assert(m.Left().Key, "key1")
t.Assert(m.Right().Key, "key4")
})
//unsafe
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewRedBlackTreeFrom(gutil.ComparatorString, expect, true)
gtest.Assert(m.Left().Key, "key1")
gtest.Assert(m.Right().Key, "key4")
t.Assert(m.Left().Key, "key1")
t.Assert(m.Right().Key, "key4")
})
}
@ -241,34 +247,34 @@ func Test_RedBlackTree_CeilingFloor(t *testing.T) {
8: "val8",
4: "val4"}
//found and eq
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewRedBlackTreeFrom(gutil.ComparatorInt, expect)
c, cf := m.Ceiling(8)
gtest.Assert(cf, true)
gtest.Assert(c.Value, "val8")
t.Assert(cf, true)
t.Assert(c.Value, "val8")
f, ff := m.Floor(20)
gtest.Assert(ff, true)
gtest.Assert(f.Value, "val20")
t.Assert(ff, true)
t.Assert(f.Value, "val20")
})
//found and neq
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewRedBlackTreeFrom(gutil.ComparatorInt, expect)
c, cf := m.Ceiling(9)
gtest.Assert(cf, true)
gtest.Assert(c.Value, "val10")
t.Assert(cf, true)
t.Assert(c.Value, "val10")
f, ff := m.Floor(5)
gtest.Assert(ff, true)
gtest.Assert(f.Value, "val4")
t.Assert(ff, true)
t.Assert(f.Value, "val4")
})
//nofound
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := gtree.NewRedBlackTreeFrom(gutil.ComparatorInt, expect)
c, cf := m.Ceiling(21)
gtest.Assert(cf, false)
gtest.Assert(c, nil)
t.Assert(cf, false)
t.Assert(c, nil)
f, ff := m.Floor(-1)
gtest.Assert(ff, false)
gtest.Assert(f, nil)
t.Assert(ff, false)
t.Assert(f, nil)
})
}
@ -278,11 +284,11 @@ func Test_RedBlackTree_Remove(t *testing.T) {
m.Set(i, fmt.Sprintf("val%d", i))
}
expect := m.Map()
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
for k, v := range expect {
m1 := m.Clone()
gtest.Assert(m1.Remove(k), v)
gtest.Assert(m1.Remove(k), nil)
t.Assert(m1.Remove(k), v)
t.Assert(m1.Remove(k), nil)
}
})
}

View File

@ -16,110 +16,110 @@ import (
)
func Test_Bool(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewBool(true)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(false), true)
gtest.AssertEQ(iClone.Val(), false)
t.AssertEQ(iClone.Set(false), true)
t.AssertEQ(iClone.Val(), false)
i1 := gtype.NewBool(false)
iClone1 := i1.Clone()
gtest.AssertEQ(iClone1.Set(true), false)
gtest.AssertEQ(iClone1.Val(), true)
t.AssertEQ(iClone1.Set(true), false)
t.AssertEQ(iClone1.Val(), true)
//空参测试
i2 := gtype.NewBool()
gtest.AssertEQ(i2.Val(), false)
t.AssertEQ(i2.Val(), false)
})
}
func Test_Bool_JSON(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewBool(true)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewBool(false)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var err error
i := gtype.NewBool()
err = json.Unmarshal([]byte("true"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), true)
t.Assert(err, nil)
t.Assert(i.Val(), true)
err = json.Unmarshal([]byte("false"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), false)
t.Assert(err, nil)
t.Assert(i.Val(), false)
err = json.Unmarshal([]byte("1"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), true)
t.Assert(err, nil)
t.Assert(i.Val(), true)
err = json.Unmarshal([]byte("0"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), false)
t.Assert(err, nil)
t.Assert(i.Val(), false)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewBool(true)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewBool()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i.Val())
t.Assert(err, nil)
t.Assert(i2.Val(), i.Val())
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewBool(false)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewBool()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i.Val())
t.Assert(err, nil)
t.Assert(i2.Val(), i.Val())
})
}
func Test_Bool_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Bool
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "true",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), true)
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), true)
})
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "false",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), false)
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), false)
})
}

View File

@ -17,13 +17,13 @@ import (
)
func Test_Byte(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var wg sync.WaitGroup
addTimes := 127
i := gtype.NewByte(byte(0))
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(byte(1)), byte(0))
gtest.AssertEQ(iClone.Val(), byte(1))
t.AssertEQ(iClone.Set(byte(1)), byte(0))
t.AssertEQ(iClone.Val(), byte(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
@ -32,46 +32,46 @@ func Test_Byte(t *testing.T) {
}()
}
wg.Wait()
gtest.AssertEQ(byte(addTimes), i.Val())
t.AssertEQ(byte(addTimes), i.Val())
//空参测试
i1 := gtype.NewByte()
gtest.AssertEQ(i1.Val(), byte(0))
t.AssertEQ(i1.Val(), byte(0))
})
}
func Test_Byte_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewByte(49)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var err error
i := gtype.NewByte()
err = json.Unmarshal([]byte("49"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), "49")
t.Assert(err, nil)
t.Assert(i.Val(), "49")
})
}
func Test_Byte_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Byte
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "2",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "2")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "2")
})
}

View File

@ -16,48 +16,48 @@ import (
)
func Test_Bytes(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewBytes([]byte("abc"))
iClone := i.Clone()
gtest.AssertEQ(iClone.Set([]byte("123")), []byte("abc"))
gtest.AssertEQ(iClone.Val(), []byte("123"))
t.AssertEQ(iClone.Set([]byte("123")), []byte("abc"))
t.AssertEQ(iClone.Val(), []byte("123"))
//空参测试
i1 := gtype.NewBytes()
gtest.AssertEQ(i1.Val(), nil)
t.AssertEQ(i1.Val(), nil)
})
}
func Test_Bytes_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
b := []byte("i love gf")
i := gtype.NewBytes(b)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewBytes()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), b)
t.Assert(err, nil)
t.Assert(i2.Val(), b)
})
}
func Test_Bytes_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Bytes
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "123")
})
}

View File

@ -16,49 +16,49 @@ import (
)
func Test_Float32(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewFloat32(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(0.1), float32(0))
gtest.AssertEQ(iClone.Val(), float32(0.1))
t.AssertEQ(iClone.Set(0.1), float32(0))
t.AssertEQ(iClone.Val(), float32(0.1))
//空参测试
i1 := gtype.NewFloat32()
gtest.AssertEQ(i1.Val(), float32(0))
t.AssertEQ(i1.Val(), float32(0))
})
}
func Test_Float32_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
v := float32(math.MaxFloat32)
i := gtype.NewFloat32(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewFloat32()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
t.Assert(err, nil)
t.Assert(i2.Val(), v)
})
}
func Test_Float32_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Float32
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123.456",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123.456")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "123.456")
})
}

View File

@ -16,47 +16,47 @@ import (
)
func Test_Float64(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewFloat64(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(0.1), float64(0))
gtest.AssertEQ(iClone.Val(), float64(0.1))
t.AssertEQ(iClone.Set(0.1), float64(0))
t.AssertEQ(iClone.Val(), float64(0.1))
//空参测试
i1 := gtype.NewFloat64()
gtest.AssertEQ(i1.Val(), float64(0))
t.AssertEQ(i1.Val(), float64(0))
})
}
func Test_Float64_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
v := math.MaxFloat64
i := gtype.NewFloat64(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewFloat64()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
t.Assert(err, nil)
t.Assert(i2.Val(), v)
})
}
func Test_Float64_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Float64
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123.456",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123.456")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "123.456")
})
}

View File

@ -17,13 +17,13 @@ import (
)
func Test_Int32(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewInt32(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), int32(0))
gtest.AssertEQ(iClone.Val(), int32(1))
t.AssertEQ(iClone.Set(1), int32(0))
t.AssertEQ(iClone.Val(), int32(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
@ -32,44 +32,44 @@ func Test_Int32(t *testing.T) {
}()
}
wg.Wait()
gtest.AssertEQ(int32(addTimes), i.Val())
t.AssertEQ(int32(addTimes), i.Val())
//空参测试
i1 := gtype.NewInt32()
gtest.AssertEQ(i1.Val(), int32(0))
t.AssertEQ(i1.Val(), int32(0))
})
}
func Test_Int32_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
v := int32(math.MaxInt32)
i := gtype.NewInt32(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewInt32()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
t.Assert(err, nil)
t.Assert(i2.Val(), v)
})
}
func Test_Int32_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Int32
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "123")
})
}

View File

@ -17,13 +17,13 @@ import (
)
func Test_Int64(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewInt64(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), int64(0))
gtest.AssertEQ(iClone.Val(), int64(1))
t.AssertEQ(iClone.Set(1), int64(0))
t.AssertEQ(iClone.Val(), int64(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
@ -32,43 +32,43 @@ func Test_Int64(t *testing.T) {
}()
}
wg.Wait()
gtest.AssertEQ(int64(addTimes), i.Val())
t.AssertEQ(int64(addTimes), i.Val())
//空参测试
i1 := gtype.NewInt64()
gtest.AssertEQ(i1.Val(), int64(0))
t.AssertEQ(i1.Val(), int64(0))
})
}
func Test_Int64_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewInt64(math.MaxInt64)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewInt64()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
t.Assert(err, nil)
t.Assert(i2.Val(), i)
})
}
func Test_Int64_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Int64
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "123")
})
}

View File

@ -16,13 +16,13 @@ import (
)
func Test_Int(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewInt(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), 0)
gtest.AssertEQ(iClone.Val(), 1)
t.AssertEQ(iClone.Set(1), 0)
t.AssertEQ(iClone.Val(), 1)
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
@ -31,44 +31,44 @@ func Test_Int(t *testing.T) {
}()
}
wg.Wait()
gtest.AssertEQ(addTimes, i.Val())
t.AssertEQ(addTimes, i.Val())
//空参测试
i1 := gtype.NewInt()
gtest.AssertEQ(i1.Val(), 0)
t.AssertEQ(i1.Val(), 0)
})
}
func Test_Int_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
v := 666
i := gtype.NewInt(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewInt()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
t.Assert(err, nil)
t.Assert(i2.Val(), v)
})
}
func Test_Int_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Int
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "123")
})
}

View File

@ -15,50 +15,50 @@ import (
)
func Test_Interface(t *testing.T) {
gtest.Case(t, func() {
t := Temp{Name: "gf", Age: 18}
t1 := Temp{Name: "gf", Age: 19}
i := gtype.New(t)
gtest.C(t, func(t *gtest.T) {
t1 := Temp{Name: "gf", Age: 18}
t2 := Temp{Name: "gf", Age: 19}
i := gtype.New(t1)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(t1), t)
gtest.AssertEQ(iClone.Val().(Temp), t1)
t.AssertEQ(iClone.Set(t2), t1)
t.AssertEQ(iClone.Val().(Temp), t2)
//空参测试
i1 := gtype.New()
gtest.AssertEQ(i1.Val(), nil)
t.AssertEQ(i1.Val(), nil)
})
}
func Test_Interface_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := "i love gf"
i := gtype.New(s)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.New()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), s)
t.Assert(err, nil)
t.Assert(i2.Val(), s)
})
}
func Test_Interface_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Interface
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "123")
})
}

View File

@ -15,48 +15,48 @@ import (
)
func Test_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewString("abc")
iClone := i.Clone()
gtest.AssertEQ(iClone.Set("123"), "abc")
gtest.AssertEQ(iClone.Val(), "123")
t.AssertEQ(iClone.Set("123"), "abc")
t.AssertEQ(iClone.Val(), "123")
//空参测试
i1 := gtype.NewString()
gtest.AssertEQ(i1.Val(), "")
t.AssertEQ(i1.Val(), "")
})
}
func Test_String_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := "i love gf"
i1 := gtype.NewString(s)
b1, err1 := json.Marshal(i1)
b2, err2 := json.Marshal(i1.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewString()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), s)
t.Assert(err, nil)
t.Assert(i2.Val(), s)
})
}
func Test_String_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.String
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "123")
})
}

View File

@ -17,13 +17,13 @@ import (
)
func Test_Uint32(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewUint32(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), uint32(0))
gtest.AssertEQ(iClone.Val(), uint32(1))
t.AssertEQ(iClone.Set(1), uint32(0))
t.AssertEQ(iClone.Val(), uint32(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
@ -32,43 +32,43 @@ func Test_Uint32(t *testing.T) {
}()
}
wg.Wait()
gtest.AssertEQ(uint32(addTimes), i.Val())
t.AssertEQ(uint32(addTimes), i.Val())
//空参测试
i1 := gtype.NewUint32()
gtest.AssertEQ(i1.Val(), uint32(0))
t.AssertEQ(i1.Val(), uint32(0))
})
}
func Test_Uint32_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewUint32(math.MaxUint32)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewUint32()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
t.Assert(err, nil)
t.Assert(i2.Val(), i)
})
}
func Test_Uint32_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Uint32
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "123")
})
}

View File

@ -23,13 +23,13 @@ type Temp struct {
}
func Test_Uint64(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewUint64(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), uint64(0))
gtest.AssertEQ(iClone.Val(), uint64(1))
t.AssertEQ(iClone.Set(1), uint64(0))
t.AssertEQ(iClone.Val(), uint64(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
@ -38,42 +38,42 @@ func Test_Uint64(t *testing.T) {
}()
}
wg.Wait()
gtest.AssertEQ(uint64(addTimes), i.Val())
t.AssertEQ(uint64(addTimes), i.Val())
//空参测试
i1 := gtype.NewUint64()
gtest.AssertEQ(i1.Val(), uint64(0))
t.AssertEQ(i1.Val(), uint64(0))
})
}
func Test_Uint64_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewUint64(math.MaxUint64)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewUint64()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
t.Assert(err, nil)
t.Assert(i2.Val(), i)
})
}
func Test_Uint64_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Uint64
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "123")
})
}

View File

@ -16,13 +16,13 @@ import (
)
func Test_Uint(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewUint(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), uint(0))
gtest.AssertEQ(iClone.Val(), uint(1))
t.AssertEQ(iClone.Set(1), uint(0))
t.AssertEQ(iClone.Val(), uint(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
@ -31,43 +31,43 @@ func Test_Uint(t *testing.T) {
}()
}
wg.Wait()
gtest.AssertEQ(uint(addTimes), i.Val())
t.AssertEQ(uint(addTimes), i.Val())
//空参测试
i1 := gtype.NewUint()
gtest.AssertEQ(i1.Val(), uint(0))
t.AssertEQ(i1.Val(), uint(0))
})
}
func Test_Uint_JSON(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
i := gtype.NewUint(666)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
t.Assert(err1, nil)
t.Assert(err2, nil)
t.Assert(b1, b2)
i2 := gtype.NewUint()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
t.Assert(err, nil)
t.Assert(i2.Val(), i)
})
}
func Test_Uint_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gtype.Uint
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.Val(), "123")
})
}

View File

@ -46,6 +46,11 @@ func Create(value interface{}, safe ...bool) Var {
return v
}
// Clone does a shallow copy of current Var and returns a pointer to this Var.
func (v *Var) Clone() *Var {
return New(v.Val(), v.safe)
}
// Set sets <value> to <v>, and returns the old value.
func (v *Var) Set(value interface{}) (old interface{}) {
if v.safe {

View File

@ -22,66 +22,66 @@ import (
)
func Test_Set(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var v gvar.Var
v.Set(123.456)
gtest.Assert(v.Val(), 123.456)
t.Assert(v.Val(), 123.456)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var v gvar.Var
v.Set(123.456)
gtest.Assert(v.Val(), 123.456)
t.Assert(v.Val(), 123.456)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
v := gvar.Create(123.456)
gtest.Assert(v.Val(), 123.456)
t.Assert(v.Val(), 123.456)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
objOne := gvar.New("old", true)
objOneOld, _ := objOne.Set("new").(string)
gtest.Assert(objOneOld, "old")
t.Assert(objOneOld, "old")
objTwo := gvar.New("old", false)
objTwoOld, _ := objTwo.Set("new").(string)
gtest.Assert(objTwoOld, "old")
t.Assert(objTwoOld, "old")
})
}
func Test_Val(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
objOne := gvar.New(1, true)
objOneOld, _ := objOne.Val().(int)
gtest.Assert(objOneOld, 1)
t.Assert(objOneOld, 1)
objTwo := gvar.New(1, false)
objTwoOld, _ := objTwo.Val().(int)
gtest.Assert(objTwoOld, 1)
t.Assert(objTwoOld, 1)
})
}
func Test_Interface(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
objOne := gvar.New(1, true)
objOneOld, _ := objOne.Interface().(int)
gtest.Assert(objOneOld, 1)
t.Assert(objOneOld, 1)
objTwo := gvar.New(1, false)
objTwoOld, _ := objTwo.Interface().(int)
gtest.Assert(objTwoOld, 1)
t.Assert(objTwoOld, 1)
})
}
func Test_IsNil(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
objOne := gvar.New(nil, true)
gtest.Assert(objOne.IsNil(), true)
t.Assert(objOne.IsNil(), true)
objTwo := gvar.New("noNil", false)
gtest.Assert(objTwo.IsNil(), false)
t.Assert(objTwo.IsNil(), false)
})
}
func Test_Bytes(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
x := int32(1)
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, x)
@ -92,233 +92,233 @@ func Test_Bytes(t *testing.T) {
var y int32
binary.Read(bBuf, binary.BigEndian, &y)
gtest.Assert(x, y)
t.Assert(x, y)
})
}
func Test_String(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var str string = "hello"
objOne := gvar.New(str, true)
gtest.Assert(objOne.String(), str)
t.Assert(objOne.String(), str)
})
}
func Test_Bool(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var ok bool = true
objOne := gvar.New(ok, true)
gtest.Assert(objOne.Bool(), ok)
t.Assert(objOne.Bool(), ok)
ok = false
objTwo := gvar.New(ok, true)
gtest.Assert(objTwo.Bool(), ok)
t.Assert(objTwo.Bool(), ok)
})
}
func Test_Int(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num int = 1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Int(), num)
t.Assert(objOne.Int(), num)
})
}
func Test_Int8(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num int8 = 1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Int8(), num)
t.Assert(objOne.Int8(), num)
})
}
func Test_Int16(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num int16 = 1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Int16(), num)
t.Assert(objOne.Int16(), num)
})
}
func Test_Int32(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num int32 = 1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Int32(), num)
t.Assert(objOne.Int32(), num)
})
}
func Test_Int64(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num int64 = 1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Int64(), num)
t.Assert(objOne.Int64(), num)
})
}
func Test_Uint(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num uint = 1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Uint(), num)
t.Assert(objOne.Uint(), num)
})
}
func Test_Uint8(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num uint8 = 1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Uint8(), num)
t.Assert(objOne.Uint8(), num)
})
}
func Test_Uint16(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num uint16 = 1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Uint16(), num)
t.Assert(objOne.Uint16(), num)
})
}
func Test_Uint32(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num uint32 = 1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Uint32(), num)
t.Assert(objOne.Uint32(), num)
})
}
func Test_Uint64(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num uint64 = 1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Uint64(), num)
t.Assert(objOne.Uint64(), num)
})
}
func Test_Float32(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num float32 = 1.1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Float32(), num)
t.Assert(objOne.Float32(), num)
})
}
func Test_Float64(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var num float64 = 1.1
objOne := gvar.New(num, true)
gtest.Assert(objOne.Float64(), num)
t.Assert(objOne.Float64(), num)
})
}
func Test_Ints(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var arr = []int{1, 2, 3, 4, 5}
objOne := gvar.New(arr, true)
gtest.Assert(objOne.Ints()[0], arr[0])
t.Assert(objOne.Ints()[0], arr[0])
})
}
func Test_Floats(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var arr = []float64{1, 2, 3, 4, 5}
objOne := gvar.New(arr, true)
gtest.Assert(objOne.Floats()[0], arr[0])
t.Assert(objOne.Floats()[0], arr[0])
})
}
func Test_Strings(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var arr = []string{"hello", "world"}
objOne := gvar.New(arr, true)
gtest.Assert(objOne.Strings()[0], arr[0])
t.Assert(objOne.Strings()[0], arr[0])
})
}
func Test_Interfaces(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var arr = []int{1, 2, 3, 4, 5}
objOne := gvar.New(arr, true)
gtest.Assert(objOne.Interfaces(), arr)
t.Assert(objOne.Interfaces(), arr)
})
}
func Test_Slice(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var arr = []int{1, 2, 3, 4, 5}
objOne := gvar.New(arr, true)
gtest.Assert(objOne.Slice(), arr)
t.Assert(objOne.Slice(), arr)
})
}
func Test_Array(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var arr = []int{1, 2, 3, 4, 5}
objOne := gvar.New(arr, false)
gtest.Assert(objOne.Array(), arr)
t.Assert(objOne.Array(), arr)
})
}
func Test_Vars(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var arr = []int{1, 2, 3, 4, 5}
objOne := gvar.New(arr, false)
gtest.Assert(len(objOne.Vars()), 5)
gtest.Assert(objOne.Vars()[0].Int(), 1)
gtest.Assert(objOne.Vars()[4].Int(), 5)
t.Assert(len(objOne.Vars()), 5)
t.Assert(objOne.Vars()[0].Int(), 1)
t.Assert(objOne.Vars()[4].Int(), 5)
})
}
func Test_Time(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var timeUnix int64 = 1556242660
objOne := gvar.New(timeUnix, true)
gtest.Assert(objOne.Time().Unix(), timeUnix)
t.Assert(objOne.Time().Unix(), timeUnix)
})
}
func Test_GTime(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var timeUnix int64 = 1556242660
objOne := gvar.New(timeUnix, true)
gtest.Assert(objOne.GTime().Unix(), timeUnix)
t.Assert(objOne.GTime().Unix(), timeUnix)
})
}
func Test_Duration(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var timeUnix int64 = 1556242660
objOne := gvar.New(timeUnix, true)
gtest.Assert(objOne.Duration(), time.Duration(timeUnix))
t.Assert(objOne.Duration(), time.Duration(timeUnix))
})
}
func Test_Map(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
m := g.Map{
"k1": "v1",
"k2": "v2",
}
objOne := gvar.New(m, true)
gtest.Assert(objOne.Map()["k1"], m["k1"])
gtest.Assert(objOne.Map()["k2"], m["k2"])
t.Assert(objOne.Map()["k1"], m["k1"])
t.Assert(objOne.Map()["k2"], m["k2"])
})
}
func Test_Struct(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
type StTest struct {
Test int
}
@ -332,76 +332,76 @@ func Test_Struct(t *testing.T) {
objOne.Struct(testObj)
gtest.Assert(testObj.Test, Kv["Test"])
t.Assert(testObj.Test, Kv["Test"])
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
type StTest struct {
Test int8
}
o := &StTest{}
v := gvar.New(g.Slice{"Test", "-25"})
v.Struct(o)
gtest.Assert(o.Test, -25)
t.Assert(o.Test, -25)
})
}
func Test_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := "i love gf"
v := gvar.New(s)
b1, err1 := json.Marshal(v)
b2, err2 := json.Marshal(s)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := int64(math.MaxInt64)
v := gvar.New(s)
b1, err1 := json.Marshal(v)
b2, err2 := json.Marshal(s)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
t.Assert(err1, err2)
t.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := "i love gf"
v := gvar.New(nil)
b, err := json.Marshal(s)
gtest.Assert(err, nil)
t.Assert(err, nil)
err = json.Unmarshal(b, v)
gtest.Assert(err, nil)
gtest.Assert(v.String(), s)
t.Assert(err, nil)
t.Assert(v.String(), s)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var v gvar.Var
s := "i love gf"
b, err := json.Marshal(s)
gtest.Assert(err, nil)
t.Assert(err, nil)
err = json.Unmarshal(b, &v)
gtest.Assert(err, nil)
gtest.Assert(v.String(), s)
t.Assert(err, nil)
t.Assert(v.String(), s)
})
}
func Test_UnmarshalValue(t *testing.T) {
type T struct {
type V struct {
Name string
Var *gvar.Var
}
gtest.Case(t, func() {
var t *T
gtest.C(t, func(t *gtest.T) {
var v *V
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "v",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.String(), "v")
}, &v)
t.Assert(err, nil)
t.Assert(v.Name, "john")
t.Assert(v.Var.String(), "v")
})
}

View File

@ -40,111 +40,111 @@ var (
)
func TestEncrypt(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
data, err := gaes.Encrypt(content, key_16)
gtest.Assert(err, nil)
gtest.Assert(data, []byte(content_16))
t.Assert(err, nil)
t.Assert(data, []byte(content_16))
data, err = gaes.Encrypt(content, key_24)
gtest.Assert(err, nil)
gtest.Assert(data, []byte(content_24))
t.Assert(err, nil)
t.Assert(data, []byte(content_24))
data, err = gaes.Encrypt(content, key_32)
gtest.Assert(err, nil)
gtest.Assert(data, []byte(content_32))
t.Assert(err, nil)
t.Assert(data, []byte(content_32))
data, err = gaes.Encrypt(content, key_16, iv)
gtest.Assert(err, nil)
gtest.Assert(data, []byte(content_16_iv))
t.Assert(err, nil)
t.Assert(data, []byte(content_16_iv))
data, err = gaes.Encrypt(content, key_32, iv)
gtest.Assert(err, nil)
gtest.Assert(data, []byte(content_32_iv))
t.Assert(err, nil)
t.Assert(data, []byte(content_32_iv))
})
}
func TestDecrypt(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
decrypt, err := gaes.Decrypt([]byte(content_16), key_16)
gtest.Assert(err, nil)
gtest.Assert(decrypt, content)
t.Assert(err, nil)
t.Assert(decrypt, content)
decrypt, err = gaes.Decrypt([]byte(content_24), key_24)
gtest.Assert(err, nil)
gtest.Assert(decrypt, content)
t.Assert(err, nil)
t.Assert(decrypt, content)
decrypt, err = gaes.Decrypt([]byte(content_32), key_32)
gtest.Assert(err, nil)
gtest.Assert(decrypt, content)
t.Assert(err, nil)
t.Assert(decrypt, content)
decrypt, err = gaes.Decrypt([]byte(content_16_iv), key_16, iv)
gtest.Assert(err, nil)
gtest.Assert(decrypt, content)
t.Assert(err, nil)
t.Assert(decrypt, content)
decrypt, err = gaes.Decrypt([]byte(content_32_iv), key_32, iv)
gtest.Assert(err, nil)
gtest.Assert(decrypt, content)
t.Assert(err, nil)
t.Assert(decrypt, content)
decrypt, err = gaes.Decrypt([]byte(content_32_iv), keys, iv)
gtest.Assert(err, "invalid padding")
t.Assert(err, "invalid padding")
})
}
func TestEncryptErr(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
// encrypt key error
_, err := gaes.Encrypt(content, key_err)
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
})
}
func TestDecryptErr(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
// decrypt key error
encrypt, err := gaes.Encrypt(content, key_16)
_, err = gaes.Decrypt(encrypt, key_err)
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
// decrypt content too short error
_, err = gaes.Decrypt([]byte("test"), key_16)
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
// decrypt content size error
_, err = gaes.Decrypt(key_17, key_16)
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
})
}
func TestPKCS5UnPaddingErr(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
// PKCS5UnPadding blockSize zero
_, err := gaes.PKCS5UnPadding(content, 0)
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
// PKCS5UnPadding src len zero
_, err = gaes.PKCS5UnPadding([]byte(""), 16)
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
// PKCS5UnPadding src len > blockSize
_, err = gaes.PKCS5UnPadding(key_17, 16)
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
// PKCS5UnPadding src len > blockSize
_, err = gaes.PKCS5UnPadding(key_32_err, 32)
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
})
}
func TestEncryptCFB(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var padding int = 0
data, err := gaes.EncryptCFB(content, key_16, &padding, iv)
gtest.Assert(err, nil)
gtest.Assert(padding, padding_size)
gtest.Assert(data, []byte(content_16_cfb))
t.Assert(err, nil)
t.Assert(padding, padding_size)
t.Assert(data, []byte(content_16_cfb))
})
}
func TestDecryptCFB(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
decrypt, err := gaes.DecryptCFB([]byte(content_16_cfb), key_16, padding_size, iv)
gtest.Assert(err, nil)
gtest.Assert(decrypt, content)
t.Assert(err, nil)
t.Assert(decrypt, content)
})
}

View File

@ -17,17 +17,17 @@ import (
)
func TestEncrypt(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s := "pibigstar"
result := 693191136
encrypt1 := gcrc32.Encrypt(s)
encrypt2 := gcrc32.Encrypt([]byte(s))
gtest.AssertEQ(int(encrypt1), result)
gtest.AssertEQ(int(encrypt2), result)
t.AssertEQ(int(encrypt1), result)
t.AssertEQ(int(encrypt2), result)
strmd5, _ := gmd5.Encrypt(s)
test1 := gcrc32.Encrypt(strmd5)
test2 := gcrc32.Encrypt([]byte(strmd5))
gtest.AssertEQ(test2, test1)
t.AssertEQ(test2, test1)
})
}

View File

@ -21,81 +21,81 @@ var (
)
func TestDesECB(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
key := []byte("11111111")
text := []byte("12345678")
padding := gdes.NOPADDING
result := "858b176da8b12503"
// encrypt test
cipherText, err := gdes.EncryptECB(text, key, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(hex.EncodeToString(cipherText), result)
t.AssertEQ(err, nil)
t.AssertEQ(hex.EncodeToString(cipherText), result)
// decrypt test
clearText, err := gdes.DecryptECB(cipherText, key, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(string(clearText), "12345678")
t.AssertEQ(err, nil)
t.AssertEQ(string(clearText), "12345678")
// encrypt err test. when throw exception,the err is not equal nil and the string is nil
errEncrypt, err := gdes.EncryptECB(text, key, errPadding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
errEncrypt, err = gdes.EncryptECB(text, errKey, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
// err decrypt test.
errDecrypt, err := gdes.DecryptECB(cipherText, errKey, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errDecrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errDecrypt, nil)
errDecrypt, err = gdes.DecryptECB(cipherText, key, errPadding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errDecrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errDecrypt, nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
key := []byte("11111111")
text := []byte("12345678")
padding := gdes.PKCS5PADDING
errPadding := 5
result := "858b176da8b12503ad6a88b4fa37833d"
cipherText, err := gdes.EncryptECB(text, key, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(hex.EncodeToString(cipherText), result)
t.AssertEQ(err, nil)
t.AssertEQ(hex.EncodeToString(cipherText), result)
// decrypt test
clearText, err := gdes.DecryptECB(cipherText, key, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(string(clearText), "12345678")
t.AssertEQ(err, nil)
t.AssertEQ(string(clearText), "12345678")
// err test
errEncrypt, err := gdes.EncryptECB(text, key, errPadding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
errDecrypt, err := gdes.DecryptECB(cipherText, errKey, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errDecrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errDecrypt, nil)
})
}
func Test3DesECB(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
key := []byte("1111111111111234")
text := []byte("1234567812345678")
padding := gdes.NOPADDING
result := "a23ee24b98c26263a23ee24b98c26263"
// encrypt test
cipherText, err := gdes.EncryptECBTriple(text, key, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(hex.EncodeToString(cipherText), result)
t.AssertEQ(err, nil)
t.AssertEQ(hex.EncodeToString(cipherText), result)
// decrypt test
clearText, err := gdes.DecryptECBTriple(cipherText, key, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(string(clearText), "1234567812345678")
t.AssertEQ(err, nil)
t.AssertEQ(string(clearText), "1234567812345678")
// err test
errEncrypt, err := gdes.EncryptECB(text, key, errPadding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
key := []byte("111111111111123412345678")
text := []byte("123456789")
padding := gdes.PKCS5PADDING
@ -103,29 +103,29 @@ func Test3DesECB(t *testing.T) {
result := "37989b1effc07a6d00ff89a7d052e79f"
// encrypt test
cipherText, err := gdes.EncryptECBTriple(text, key, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(hex.EncodeToString(cipherText), result)
t.AssertEQ(err, nil)
t.AssertEQ(hex.EncodeToString(cipherText), result)
// decrypt test
clearText, err := gdes.DecryptECBTriple(cipherText, key, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(string(clearText), "123456789")
t.AssertEQ(err, nil)
t.AssertEQ(string(clearText), "123456789")
// err test, when key is err, but text and padding is right
errEncrypt, err := gdes.EncryptECBTriple(text, errKey, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
// when padding is err,but key and text is right
errEncrypt, err = gdes.EncryptECBTriple(text, key, errPadding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
// decrypt err test,when key is err
errEncrypt, err = gdes.DecryptECBTriple(text, errKey, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
})
}
func TestDesCBC(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
key := []byte("11111111")
text := []byte("1234567812345678")
padding := gdes.NOPADDING
@ -133,39 +133,39 @@ func TestDesCBC(t *testing.T) {
result := "40826a5800608c87585ca7c9efabee47"
// encrypt test
cipherText, err := gdes.EncryptCBC(text, key, iv, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(hex.EncodeToString(cipherText), result)
t.AssertEQ(err, nil)
t.AssertEQ(hex.EncodeToString(cipherText), result)
// decrypt test
clearText, err := gdes.DecryptCBC(cipherText, key, iv, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(string(clearText), "1234567812345678")
t.AssertEQ(err, nil)
t.AssertEQ(string(clearText), "1234567812345678")
// encrypt err test.
errEncrypt, err := gdes.EncryptCBC(text, errKey, iv, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
// the iv is err
errEncrypt, err = gdes.EncryptCBC(text, key, errIv, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
// the padding is err
errEncrypt, err = gdes.EncryptCBC(text, key, iv, errPadding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
// decrypt err test. the key is err
errDecrypt, err := gdes.DecryptCBC(cipherText, errKey, iv, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errDecrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errDecrypt, nil)
// the iv is err
errDecrypt, err = gdes.DecryptCBC(cipherText, key, errIv, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errDecrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errDecrypt, nil)
// the padding is err
errDecrypt, err = gdes.DecryptCBC(cipherText, key, iv, errPadding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errDecrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errDecrypt, nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
key := []byte("11111111")
text := []byte("12345678")
padding := gdes.PKCS5PADDING
@ -173,21 +173,21 @@ func TestDesCBC(t *testing.T) {
result := "40826a5800608c87100a25d86ac7c52c"
// encrypt test
cipherText, err := gdes.EncryptCBC(text, key, iv, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(hex.EncodeToString(cipherText), result)
t.AssertEQ(err, nil)
t.AssertEQ(hex.EncodeToString(cipherText), result)
// decrypt test
clearText, err := gdes.DecryptCBC(cipherText, key, iv, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(string(clearText), "12345678")
t.AssertEQ(err, nil)
t.AssertEQ(string(clearText), "12345678")
// err test
errEncrypt, err := gdes.EncryptCBC(text, key, errIv, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
})
}
func Test3DesCBC(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
key := []byte("1111111112345678")
text := []byte("1234567812345678")
padding := gdes.NOPADDING
@ -195,38 +195,38 @@ func Test3DesCBC(t *testing.T) {
result := "bfde1394e265d5f738d5cab170c77c88"
// encrypt test
cipherText, err := gdes.EncryptCBCTriple(text, key, iv, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(hex.EncodeToString(cipherText), result)
t.AssertEQ(err, nil)
t.AssertEQ(hex.EncodeToString(cipherText), result)
// decrypt test
clearText, err := gdes.DecryptCBCTriple(cipherText, key, iv, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(string(clearText), "1234567812345678")
t.AssertEQ(err, nil)
t.AssertEQ(string(clearText), "1234567812345678")
// encrypt err test
errEncrypt, err := gdes.EncryptCBCTriple(text, errKey, iv, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
// the iv is err
errEncrypt, err = gdes.EncryptCBCTriple(text, key, errIv, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
// the padding is err
errEncrypt, err = gdes.EncryptCBCTriple(text, key, iv, errPadding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errEncrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errEncrypt, nil)
// decrypt err test
errDecrypt, err := gdes.DecryptCBCTriple(cipherText, errKey, iv, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errDecrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errDecrypt, nil)
// the iv is err
errDecrypt, err = gdes.DecryptCBCTriple(cipherText, key, errIv, padding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errDecrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errDecrypt, nil)
// the padding is err
errDecrypt, err = gdes.DecryptCBCTriple(cipherText, key, iv, errPadding)
gtest.AssertNE(err, nil)
gtest.AssertEQ(errDecrypt, nil)
t.AssertNE(err, nil)
t.AssertEQ(errDecrypt, nil)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
key := []byte("111111111234567812345678")
text := []byte("12345678")
padding := gdes.PKCS5PADDING
@ -234,12 +234,12 @@ func Test3DesCBC(t *testing.T) {
result := "40826a5800608c87100a25d86ac7c52c"
// encrypt test
cipherText, err := gdes.EncryptCBCTriple(text, key, iv, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(hex.EncodeToString(cipherText), result)
t.AssertEQ(err, nil)
t.AssertEQ(hex.EncodeToString(cipherText), result)
// decrypt test
clearText, err := gdes.DecryptCBCTriple(cipherText, key, iv, padding)
gtest.AssertEQ(err, nil)
gtest.AssertEQ(string(clearText), "12345678")
t.AssertEQ(err, nil)
t.AssertEQ(string(clearText), "12345678")
})
}

View File

@ -29,16 +29,16 @@ type user struct {
}
func TestEncrypt(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
encryptString, _ := gmd5.Encrypt(s)
gtest.Assert(encryptString, result)
t.Assert(encryptString, result)
result := "1427562bb29f88a1161590b76398ab72"
encrypt, _ := gmd5.Encrypt(123456)
gtest.AssertEQ(encrypt, result)
t.AssertEQ(encrypt, result)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
user := &user{
name: "派大星",
password: "123456",
@ -46,14 +46,14 @@ func TestEncrypt(t *testing.T) {
}
result := "70917ebce8bd2f78c736cda63870fb39"
encrypt, _ := gmd5.Encrypt(user)
gtest.AssertEQ(encrypt, result)
t.AssertEQ(encrypt, result)
})
}
func TestEncryptString(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
encryptString, _ := gmd5.EncryptString(s)
gtest.Assert(encryptString, result)
t.Assert(encryptString, result)
})
}
@ -61,17 +61,17 @@ func TestEncryptFile(t *testing.T) {
path := "test.text"
errorPath := "err.txt"
result := "e6e6e1cd41895beebff16d5452dfce12"
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
file, err := os.Create(path)
defer os.Remove(path)
defer file.Close()
gtest.Assert(err, nil)
t.Assert(err, nil)
_, _ = file.Write([]byte("Hello Go Frame"))
encryptFile, _ := gmd5.EncryptFile(path)
gtest.AssertEQ(encryptFile, result)
t.AssertEQ(encryptFile, result)
// when the file is not exist,encrypt will return empty string
errEncrypt, _ := gmd5.EncryptFile(errorPath)
gtest.AssertEQ(errEncrypt, "")
t.AssertEQ(errEncrypt, "")
})
}

View File

@ -23,7 +23,7 @@ type user struct {
}
func TestEncrypt(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
user := &user{
name: "派大星",
password: "123456",
@ -31,29 +31,29 @@ func TestEncrypt(t *testing.T) {
}
result := "97386736e3ee4adee5ca595c78c12129f6032cad"
encrypt := gsha1.Encrypt(user)
gtest.AssertEQ(encrypt, result)
t.AssertEQ(encrypt, result)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
result := "5b4c1c2a08ca85ddd031ef8627414f4cb2620b41"
s := gsha1.Encrypt("pibigstar")
gtest.AssertEQ(s, result)
t.AssertEQ(s, result)
})
}
func TestEncryptFile(t *testing.T) {
path := "test.text"
errPath := "err.text"
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
result := "8b05d3ba24b8d2374b8f5149d9f3fbada14ea984"
file, err := os.Create(path)
defer os.Remove(path)
defer file.Close()
gtest.Assert(err, nil)
t.Assert(err, nil)
_, _ = file.Write([]byte("Hello Go Frame"))
encryptFile, _ := gsha1.EncryptFile(path)
gtest.AssertEQ(encryptFile, result)
t.AssertEQ(encryptFile, result)
// when the file is not exist,encrypt will return empty string
errEncrypt, _ := gsha1.EncryptFile(errPath)
gtest.AssertEQ(errEncrypt, "")
t.AssertEQ(errEncrypt, "")
})
}

View File

@ -11,6 +11,7 @@ import (
"database/sql"
"errors"
"fmt"
"github.com/gogf/gf/internal/intlog"
"time"
"github.com/gogf/gf/os/glog"
@ -29,29 +30,29 @@ type DB interface {
Open(config *ConfigNode) (*sql.DB, error)
// Query APIs.
Query(query string, args ...interface{}) (*sql.Rows, error)
Query(sql string, args ...interface{}) (*sql.Rows, error)
Exec(sql string, args ...interface{}) (sql.Result, error)
Prepare(sql string, execOnMaster ...bool) (*sql.Stmt, error)
// Internal APIs for CURD, which can be overwrote for custom CURD implements.
DoQuery(link Link, query string, args ...interface{}) (rows *sql.Rows, err error)
DoGetAll(link Link, query string, args ...interface{}) (result Result, err error)
DoExec(link Link, query string, args ...interface{}) (result sql.Result, err error)
DoPrepare(link Link, query string) (*sql.Stmt, error)
DoQuery(link Link, sql string, args ...interface{}) (rows *sql.Rows, err error)
DoGetAll(link Link, sql string, args ...interface{}) (result Result, err error)
DoExec(link Link, sql string, args ...interface{}) (result sql.Result, err error)
DoPrepare(link Link, sql string) (*sql.Stmt, error)
DoInsert(link Link, table string, data interface{}, option int, batch ...int) (result sql.Result, err error)
DoBatchInsert(link Link, table string, list interface{}, option int, batch ...int) (result sql.Result, err error)
DoUpdate(link Link, table string, data interface{}, condition string, args ...interface{}) (result sql.Result, err error)
DoDelete(link Link, table string, condition string, args ...interface{}) (result sql.Result, err error)
// Query APIs for convenience purpose.
GetAll(query string, args ...interface{}) (Result, error)
GetOne(query string, args ...interface{}) (Record, error)
GetValue(query string, args ...interface{}) (Value, error)
GetArray(query string, args ...interface{}) ([]Value, error)
GetCount(query string, args ...interface{}) (int, error)
GetStruct(objPointer interface{}, query string, args ...interface{}) error
GetStructs(objPointerSlice interface{}, query string, args ...interface{}) error
GetScan(objPointer interface{}, query string, args ...interface{}) error
GetAll(sql string, args ...interface{}) (Result, error)
GetOne(sql string, args ...interface{}) (Record, error)
GetValue(sql string, args ...interface{}) (Value, error)
GetArray(sql string, args ...interface{}) ([]Value, error)
GetCount(sql string, args ...interface{}) (int, error)
GetStruct(objPointer interface{}, sql string, args ...interface{}) error
GetStructs(objPointerSlice interface{}, sql string, args ...interface{}) error
GetScan(objPointer interface{}, sql string, args ...interface{}) error
// Master/Slave specification support.
Master() (*sql.DB, error)
@ -106,9 +107,9 @@ type DB interface {
// HandleSqlBeforeCommit is a hook function, which deals with the sql string before
// it's committed to underlying driver. The parameter <link> specifies the current
// database connection operation object. You can modify the sql string <query> and its
// database connection operation object. You can modify the sql string <sql> and its
// arguments <args> as you wish before they're committed to driver.
HandleSqlBeforeCommit(link Link, query string, args []interface{}) (string, []interface{})
HandleSqlBeforeCommit(link Link, sql string, args []interface{}) (string, []interface{})
// Internal methods.
filterFields(schema, table string, data map[string]interface{}) map[string]interface{}
@ -160,7 +161,7 @@ type TableField struct {
// Link is a common database function wrapper interface.
type Link interface {
Query(query string, args ...interface{}) (*sql.Rows, error)
Query(sql string, args ...interface{}) (*sql.Rows, error)
Exec(sql string, args ...interface{}) (sql.Result, error)
Prepare(sql string) (*sql.Stmt, error)
}
@ -192,6 +193,8 @@ const (
)
var (
// ErrNoRows is alias of sql.ErrNoRows.
ErrNoRows = sql.ErrNoRows
// instances is the management map for instances.
instances = gmap.NewStrAnyMap(true)
// driverMap manages all custom registered driver.
@ -370,6 +373,7 @@ func (c *Core) getSqlDb(master bool, schema ...string) (sqlDb *sql.DB, err error
v := c.cache.GetOrSetFuncLock(node.String(), func() interface{} {
sqlDb, err = c.DB.Open(node)
if err != nil {
intlog.Printf("DB open failed: %v, %+v", err, node)
return nil
}
if c.maxIdleConnCount > 0 {

View File

@ -45,75 +45,75 @@ func (c *Core) Slave() (*sql.DB, error) {
// Query commits one query SQL to underlying driver and returns the execution result.
// It is most commonly used for data querying.
func (c *Core) Query(query string, args ...interface{}) (rows *sql.Rows, err error) {
func (c *Core) Query(sql string, args ...interface{}) (rows *sql.Rows, err error) {
link, err := c.DB.Slave()
if err != nil {
return nil, err
}
return c.DB.DoQuery(link, query, args...)
return c.DB.DoQuery(link, sql, args...)
}
// doQuery commits the query string and its arguments to underlying driver
// DoQuery commits the sql string and its arguments to underlying driver
// through given link object and returns the execution result.
func (c *Core) DoQuery(link Link, query string, args ...interface{}) (rows *sql.Rows, err error) {
query, args = formatQuery(query, args)
query, args = c.DB.HandleSqlBeforeCommit(link, query, args)
func (c *Core) DoQuery(link Link, sql string, args ...interface{}) (rows *sql.Rows, err error) {
sql, args = formatSql(sql, args)
sql, args = c.DB.HandleSqlBeforeCommit(link, sql, args)
if c.DB.GetDebug() {
mTime1 := gtime.TimestampMilli()
rows, err = link.Query(query, args...)
rows, err = link.Query(sql, args...)
mTime2 := gtime.TimestampMilli()
s := &Sql{
Sql: query,
Sql: sql,
Args: args,
Format: bindArgsToQuery(query, args),
Format: FormatSqlWithArgs(sql, args),
Error: err,
Start: mTime1,
End: mTime2,
}
c.writeSqlToLogger(s)
} else {
rows, err = link.Query(query, args...)
rows, err = link.Query(sql, args...)
}
if err == nil {
return rows, nil
} else {
err = formatError(err, query, args...)
err = formatError(err, sql, args...)
}
return nil, err
}
// Exec commits one query SQL to underlying driver and returns the execution result.
// It is most commonly used for data inserting and updating.
func (c *Core) Exec(query string, args ...interface{}) (result sql.Result, err error) {
func (c *Core) Exec(sql string, args ...interface{}) (result sql.Result, err error) {
link, err := c.DB.Master()
if err != nil {
return nil, err
}
return c.DB.DoExec(link, query, args...)
return c.DB.DoExec(link, sql, args...)
}
// doExec commits the query string and its arguments to underlying driver
// DoExec commits the sql string and its arguments to underlying driver
// through given link object and returns the execution result.
func (c *Core) DoExec(link Link, query string, args ...interface{}) (result sql.Result, err error) {
query, args = formatQuery(query, args)
query, args = c.DB.HandleSqlBeforeCommit(link, query, args)
func (c *Core) DoExec(link Link, sql string, args ...interface{}) (result sql.Result, err error) {
sql, args = formatSql(sql, args)
sql, args = c.DB.HandleSqlBeforeCommit(link, sql, args)
if c.DB.GetDebug() {
mTime1 := gtime.TimestampMilli()
result, err = link.Exec(query, args...)
result, err = link.Exec(sql, args...)
mTime2 := gtime.TimestampMilli()
s := &Sql{
Sql: query,
Sql: sql,
Args: args,
Format: bindArgsToQuery(query, args),
Format: FormatSqlWithArgs(sql, args),
Error: err,
Start: mTime1,
End: mTime2,
}
c.writeSqlToLogger(s)
} else {
result, err = link.Exec(query, args...)
result, err = link.Exec(sql, args...)
}
return result, formatError(err, query, args...)
return result, formatError(err, sql, args...)
}
// Prepare creates a prepared statement for later queries or executions.
@ -124,7 +124,7 @@ func (c *Core) DoExec(link Link, query string, args ...interface{}) (result sql.
//
// The parameter <execOnMaster> specifies whether executing the sql on master node,
// or else it executes the sql on slave node if master-slave configured.
func (c *Core) Prepare(query string, execOnMaster ...bool) (*sql.Stmt, error) {
func (c *Core) Prepare(sql string, execOnMaster ...bool) (*sql.Stmt, error) {
err := (error)(nil)
link := (Link)(nil)
if len(execOnMaster) > 0 && execOnMaster[0] {
@ -136,28 +136,28 @@ func (c *Core) Prepare(query string, execOnMaster ...bool) (*sql.Stmt, error) {
return nil, err
}
}
return c.DB.DoPrepare(link, query)
return c.DB.DoPrepare(link, sql)
}
// doPrepare calls prepare function on given link object and returns the statement object.
func (c *Core) DoPrepare(link Link, query string) (*sql.Stmt, error) {
return link.Prepare(query)
func (c *Core) DoPrepare(link Link, sql string) (*sql.Stmt, error) {
return link.Prepare(sql)
}
// GetAll queries and returns data records from database.
func (c *Core) GetAll(query string, args ...interface{}) (Result, error) {
return c.DB.DoGetAll(nil, query, args...)
func (c *Core) GetAll(sql string, args ...interface{}) (Result, error) {
return c.DB.DoGetAll(nil, sql, args...)
}
// doGetAll queries and returns data records from database.
func (c *Core) DoGetAll(link Link, query string, args ...interface{}) (result Result, err error) {
func (c *Core) DoGetAll(link Link, sql string, args ...interface{}) (result Result, err error) {
if link == nil {
link, err = c.DB.Slave()
if err != nil {
return nil, err
}
}
rows, err := c.DB.DoQuery(link, query, args...)
rows, err := c.DB.DoQuery(link, sql, args...)
if err != nil || rows == nil {
return nil, err
}
@ -166,8 +166,8 @@ func (c *Core) DoGetAll(link Link, query string, args ...interface{}) (result Re
}
// GetOne queries and returns one record from database.
func (c *Core) GetOne(query string, args ...interface{}) (Record, error) {
list, err := c.DB.GetAll(query, args...)
func (c *Core) GetOne(sql string, args ...interface{}) (Record, error) {
list, err := c.DB.GetAll(sql, args...)
if err != nil {
return nil, err
}
@ -179,8 +179,8 @@ func (c *Core) GetOne(query string, args ...interface{}) (Record, error) {
// GetArray queries and returns data values as slice from database.
// Note that if there're multiple columns in the result, it returns just one column values randomly.
func (c *Core) GetArray(query string, args ...interface{}) ([]Value, error) {
all, err := c.DB.DoGetAll(nil, query, args...)
func (c *Core) GetArray(sql string, args ...interface{}) ([]Value, error) {
all, err := c.DB.DoGetAll(nil, sql, args...)
if err != nil {
return nil, err
}
@ -189,26 +189,26 @@ func (c *Core) GetArray(query string, args ...interface{}) ([]Value, error) {
// GetStruct queries one record from database and converts it to given struct.
// The parameter <pointer> should be a pointer to struct.
func (c *Core) GetStruct(pointer interface{}, query string, args ...interface{}) error {
one, err := c.DB.GetOne(query, args...)
func (c *Core) GetStruct(pointer interface{}, sql string, args ...interface{}) error {
one, err := c.DB.GetOne(sql, args...)
if err != nil {
return err
}
if len(one) == 0 {
return sql.ErrNoRows
return ErrNoRows
}
return one.Struct(pointer)
}
// GetStructs queries records from database and converts them to given struct.
// The parameter <pointer> should be type of struct slice: []struct/[]*struct.
func (c *Core) GetStructs(pointer interface{}, query string, args ...interface{}) error {
all, err := c.DB.GetAll(query, args...)
func (c *Core) GetStructs(pointer interface{}, sql string, args ...interface{}) error {
all, err := c.DB.GetAll(sql, args...)
if err != nil {
return err
}
if len(all) == 0 {
return sql.ErrNoRows
return ErrNoRows
}
return all.Structs(pointer)
}
@ -219,7 +219,7 @@ func (c *Core) GetStructs(pointer interface{}, query string, args ...interface{}
// If parameter <pointer> is type of struct pointer, it calls GetStruct internally for
// the conversion. If parameter <pointer> is type of slice, it calls GetStructs internally
// for conversion.
func (c *Core) GetScan(pointer interface{}, query string, args ...interface{}) error {
func (c *Core) GetScan(pointer interface{}, sql string, args ...interface{}) error {
t := reflect.TypeOf(pointer)
k := t.Kind()
if k != reflect.Ptr {
@ -228,9 +228,9 @@ func (c *Core) GetScan(pointer interface{}, query string, args ...interface{}) e
k = t.Elem().Kind()
switch k {
case reflect.Array, reflect.Slice:
return c.DB.GetStructs(pointer, query, args...)
return c.DB.GetStructs(pointer, sql, args...)
case reflect.Struct:
return c.DB.GetStruct(pointer, query, args...)
return c.DB.GetStruct(pointer, sql, args...)
}
return fmt.Errorf("element type should be type of struct/slice, unsupported: %v", k)
}
@ -238,8 +238,8 @@ func (c *Core) GetScan(pointer interface{}, query string, args ...interface{}) e
// GetValue queries and returns the field value from database.
// The sql should queries only one field from database, or else it returns only one
// field of the result.
func (c *Core) GetValue(query string, args ...interface{}) (Value, error) {
one, err := c.DB.GetOne(query, args...)
func (c *Core) GetValue(sql string, args ...interface{}) (Value, error) {
one, err := c.DB.GetOne(sql, args...)
if err != nil {
return nil, err
}
@ -250,13 +250,13 @@ func (c *Core) GetValue(query string, args ...interface{}) (Value, error) {
}
// GetCount queries and returns the count from database.
func (c *Core) GetCount(query string, args ...interface{}) (int, error) {
func (c *Core) GetCount(sql string, args ...interface{}) (int, error) {
// If the query fields do not contains function "COUNT",
// it replaces the query string and adds the "COUNT" function to the fields.
if !gregex.IsMatchString(`(?i)SELECT\s+COUNT\(.+\)\s+FROM`, query) {
query, _ = gregex.ReplaceString(`(?i)(SELECT)\s+(.+)\s+(FROM)`, `$1 COUNT($2) $3`, query)
// it replaces the sql string and adds the "COUNT" function to the fields.
if !gregex.IsMatchString(`(?i)SELECT\s+COUNT\(.+\)\s+FROM`, sql) {
sql, _ = gregex.ReplaceString(`(?i)(SELECT)\s+(.+)\s+(FROM)`, `$1 COUNT($2) $3`, sql)
}
value, err := c.DB.GetValue(query, args...)
value, err := c.DB.GetValue(sql, args...)
if err != nil {
return 0, err
}

View File

@ -60,10 +60,10 @@ func (d *DriverMssql) GetChars() (charLeft string, charRight string) {
}
// HandleSqlBeforeCommit deals with the sql string before commits it to underlying sql driver.
func (d *DriverMssql) HandleSqlBeforeCommit(link Link, query string, args []interface{}) (string, []interface{}) {
func (d *DriverMssql) HandleSqlBeforeCommit(link Link, sql string, args []interface{}) (string, []interface{}) {
var index int
// Convert place holder char '?' to string "@px".
str, _ := gregex.ReplaceStringFunc("\\?", query, func(s string) string {
str, _ := gregex.ReplaceStringFunc("\\?", sql, func(s string) string {
index++
return fmt.Sprintf("@p%d", index)
})
@ -71,6 +71,8 @@ func (d *DriverMssql) HandleSqlBeforeCommit(link Link, query string, args []inte
return d.parseSql(str), args
}
// parseSql does some replacement of the sql before commits it to underlying driver,
// for support of microsoft sql server.
func (d *DriverMssql) parseSql(sql string) string {
// SELECT * FROM USER WHERE ID=1 LIMIT 1
if m, _ := gregex.MatchString(`^SELECT(.+)LIMIT 1$`, sql); len(m) > 1 {
@ -91,22 +93,20 @@ func (d *DriverMssql) parseSql(sql string) string {
index++
switch keyword {
case "SELECT":
// 不含LIMIT关键字则不处理
// LIMIT statement checks.
if len(res) < 2 ||
(strings.HasPrefix(res[index][0], "LIMIT") == false &&
strings.HasPrefix(res[index][0], "limit") == false) {
break
}
// 不含LIMIT则不处理
if gregex.IsMatchString("((?i)SELECT)(.+)((?i)LIMIT)", sql) == false {
break
}
// 判断SQL中是否含有order by
// ORDER BY statement checks.
selectStr := ""
orderStr := ""
haveOrder := gregex.IsMatchString("((?i)SELECT)(.+)((?i)ORDER BY)", sql)
if haveOrder {
// 取order by 前面的字符串
queryExpr, _ := gregex.MatchString("((?i)SELECT)(.+)((?i)ORDER BY)", sql)
if len(queryExpr) != 4 ||
strings.EqualFold(queryExpr[1], "SELECT") == false ||
@ -114,8 +114,6 @@ func (d *DriverMssql) parseSql(sql string) string {
break
}
selectStr = queryExpr[2]
// 取order by表达式的值
orderExpr, _ := gregex.MatchString("((?i)ORDER BY)(.+)((?i)LIMIT)", sql)
if len(orderExpr) != 4 ||
strings.EqualFold(orderExpr[1], "ORDER BY") == false ||
@ -132,8 +130,6 @@ func (d *DriverMssql) parseSql(sql string) string {
}
selectStr = queryExpr[2]
}
// 取limit后面的取值范围
first, limit := 0, 0
for i := 1; i < len(res[index]); i++ {
if len(strings.TrimSpace(res[index][i])) == 0 {
@ -147,23 +143,20 @@ func (d *DriverMssql) parseSql(sql string) string {
break
}
}
if haveOrder {
sql = fmt.Sprintf(
"SELECT * FROM "+
"(SELECT ROW_NUMBER() OVER (ORDER BY %s) as ROWNUMBER_, %s ) as TMP_ "+
"WHERE TMP_.ROWNUMBER_ > %d AND TMP_.ROWNUMBER_ <= %d",
orderStr, selectStr, first, limit,
orderStr, selectStr, first, first+limit,
)
} else {
if first == 0 {
first = limit
} else {
first = limit - first
}
sql = fmt.Sprintf(
"SELECT * FROM (SELECT TOP %d * FROM (SELECT TOP %d %s) as TMP1_ ) as TMP2_ ",
first, limit, selectStr,
limit, first+limit, selectStr,
)
}
default:

View File

@ -64,10 +64,10 @@ func (d *DriverOracle) GetChars() (charLeft string, charRight string) {
}
// HandleSqlBeforeCommit deals with the sql string before commits it to underlying sql driver.
func (d *DriverOracle) HandleSqlBeforeCommit(link Link, query string, args []interface{}) (string, []interface{}) {
func (d *DriverOracle) HandleSqlBeforeCommit(link Link, sql string, args []interface{}) (string, []interface{}) {
var index int
// Convert place holder char '?' to string ":x".
str, _ := gregex.ReplaceStringFunc("\\?", query, func(s string) string {
str, _ := gregex.ReplaceStringFunc("\\?", sql, func(s string) string {
index++
return fmt.Sprintf(":%d", index)
})
@ -75,6 +75,8 @@ func (d *DriverOracle) HandleSqlBeforeCommit(link Link, query string, args []int
return d.parseSql(str), args
}
// parseSql does some replacement of the sql before commits it to underlying driver,
// for support of oracle server.
func (d *DriverOracle) parseSql(sql string) string {
patten := `^\s*(?i)(SELECT)|(LIMIT\s*(\d+)\s*,\s*(\d+))`
if gregex.IsMatchString(patten, sql) == false {
@ -93,22 +95,18 @@ func (d *DriverOracle) parseSql(sql string) string {
index++
switch keyword {
case "SELECT":
// 不含LIMIT关键字则不处理
if len(res) < 2 || (strings.HasPrefix(res[index][0], "LIMIT") == false && strings.HasPrefix(res[index][0], "limit") == false) {
if len(res) < 2 || (strings.HasPrefix(res[index][0], "LIMIT") == false &&
strings.HasPrefix(res[index][0], "limit") == false) {
break
}
// 取limit前面的字符串
if gregex.IsMatchString("((?i)SELECT)(.+)((?i)LIMIT)", sql) == false {
break
}
queryExpr, _ := gregex.MatchString("((?i)SELECT)(.+)((?i)LIMIT)", sql)
if len(queryExpr) != 4 || strings.EqualFold(queryExpr[1], "SELECT") == false || strings.EqualFold(queryExpr[3], "LIMIT") == false {
if len(queryExpr) != 4 || strings.EqualFold(queryExpr[1], "SELECT") == false ||
strings.EqualFold(queryExpr[3], "LIMIT") == false {
break
}
// 取limit后面的取值范围
first, limit := 0, 0
for i := 1; i < len(res[index]); i++ {
if len(strings.TrimSpace(res[index][i])) == 0 {
@ -121,10 +119,10 @@ func (d *DriverOracle) parseSql(sql string) string {
break
}
}
// 也可以使用between,据说这种写法的性能会比between好点,里层SQL中的ROWNUM_ >= limit可以缩小查询后的数据集规模
sql = fmt.Sprintf(
"SELECT * FROM (SELECT GFORM.*, ROWNUM ROWNUM_ FROM (%s %s) GFORM WHERE ROWNUM <= %d) WHERE ROWNUM_ >= %d",
"SELECT * FROM "+
"(SELECT GFORM.*, ROWNUM ROWNUM_ FROM (%s %s) GFORM WHERE ROWNUM <= %d)"+
" WHERE ROWNUM_ >= %d",
queryExpr[1], queryExpr[2], limit, first,
)
}

View File

@ -14,6 +14,7 @@ import (
"database/sql"
"fmt"
"github.com/gogf/gf/internal/intlog"
"github.com/gogf/gf/os/gfile"
"github.com/gogf/gf/text/gstr"
"strings"
)
@ -34,11 +35,16 @@ func (d *DriverSqlite) New(core *Core, node *ConfigNode) (DB, error) {
// Open creates and returns a underlying sql.DB object for sqlite.
func (d *DriverSqlite) Open(config *ConfigNode) (*sql.DB, error) {
var source string
var err error
if config.LinkInfo != "" {
source = config.LinkInfo
} else {
source = config.Name
}
source, err = gfile.Search(source)
if err != nil {
return nil, err
}
intlog.Printf("Open: %s", source)
if db, err := sql.Open("sqlite3", source); err == nil {
return db, nil
@ -53,8 +59,8 @@ func (d *DriverSqlite) GetChars() (charLeft string, charRight string) {
}
// HandleSqlBeforeCommit deals with the sql string before commits it to underlying sql driver.
// @todo 需要增加对Save方法的支持可使用正则来实现替换
// @todo 将ON DUPLICATE KEY UPDATE触发器修改为两条SQL语句(INSERT OR IGNORE & UPDATE)
// TODO 需要增加对Save方法的支持可使用正则来实现替换
// TODO 将ON DUPLICATE KEY UPDATE触发器修改为两条SQL语句(INSERT OR IGNORE & UPDATE)
func (d *DriverSqlite) HandleSqlBeforeCommit(link Link, sql string, args []interface{}) (string, []interface{}) {
return sql, args
}

View File

@ -8,7 +8,6 @@ package gdb
import (
"bytes"
"database/sql"
"errors"
"fmt"
"github.com/gogf/gf/internal/empty"
@ -41,6 +40,11 @@ type apiInterfaces interface {
Interfaces() []interface{}
}
// apiMapStrAny is the interface support for converting struct parameter to map.
type apiMapStrAny interface {
MapStrAny() map[string]interface{}
}
const (
ORM_TAG_FOR_STRUCT = "orm"
ORM_TAG_FOR_UNIQUE = "unique"
@ -99,21 +103,27 @@ func DataToMapDeep(obj interface{}) map[string]interface{} {
return data
}
// QuotePrefixTableName adds prefix string and quote chars for the table. It handles table string like:
// "user", "user u", "user,user_detail", "user u, user_detail ut", "user as u, user_detail as ut", "user.user u".
// doHandleTableName adds prefix string and quote chars for the table. It handles table string like:
// "user", "user u", "user,user_detail", "user u, user_detail ut", "user as u, user_detail as ut",
// "user.user u", "`user`.`user` u".
//
// Note that, this will automatically checks the table prefix whether already added, if true it does
// nothing to the table name, or else adds the prefix to the table name.
func doHandleTableName(table, prefix, charLeft, charRight string) string {
index := 0
array1 := gstr.SplitAndTrim(table, ",")
var (
index = 0
chars = charLeft + charRight
array1 = gstr.SplitAndTrim(table, ",")
)
for k1, v1 := range array1 {
array2 := gstr.SplitAndTrim(v1, " ")
// Trim the security chars.
array2[0] = gstr.TrimLeftStr(array2[0], charLeft)
array2[0] = gstr.TrimRightStr(array2[0], charRight)
array2[0] = gstr.Trim(array2[0], chars)
// Check whether it has database name.
array3 := gstr.Split(gstr.Trim(array2[0]), ".")
for k, v := range array3 {
array3[k] = gstr.Trim(v, chars)
}
index = len(array3) - 1
// If the table name already has the prefix, skips the prefix adding.
if len(array3[index]) <= len(prefix) || array3[index][:len(prefix)] != prefix {
@ -222,11 +232,11 @@ func GetPrimaryKeyCondition(primary string, where ...interface{}) (newWhereCondi
return where
}
// formatQuery formats the query string and its arguments before executing.
// formatSql formats the sql string and its arguments before executing.
// The internal handleArguments function might be called twice during the SQL procedure,
// but do not worry about it, it's safe and efficient.
func formatQuery(query string, args []interface{}) (newQuery string, newArgs []interface{}) {
return handleArguments(query, args)
func formatSql(sql string, args []interface{}) (newQuery string, newArgs []interface{}) {
return handleArguments(sql, args)
}
// formatWhere formats where statement and its arguments.
@ -384,8 +394,8 @@ func formatWhereKeyValue(db DB, buffer *bytes.Buffer, newArgs []interface{}, key
// handleArguments is a nice function which handles the query and its arguments before committing to
// underlying driver.
func handleArguments(query string, args []interface{}) (newQuery string, newArgs []interface{}) {
newQuery = query
func handleArguments(sql string, args []interface{}) (newSql string, newArgs []interface{}) {
newSql = sql
// Handles the slice arguments.
if len(args) > 0 {
for index, arg := range args {
@ -409,12 +419,12 @@ func handleArguments(query string, args []interface{}) (newQuery string, newArgs
// It the '?' holder count equals the length of the slice,
// it does not implement the arguments splitting logic.
// Eg: db.Query("SELECT ?+?", g.Slice{1, 2})
if len(args) == 1 && gstr.Count(newQuery, "?") == rv.Len() {
if len(args) == 1 && gstr.Count(newSql, "?") == rv.Len() {
break
}
// counter is used to finding the inserting position for the '?' holder.
counter := 0
newQuery, _ = gregex.ReplaceStringFunc(`\?`, newQuery, func(s string) string {
newSql, _ = gregex.ReplaceStringFunc(`\?`, newSql, func(s string) string {
counter++
if counter == index+1 {
return "?" + strings.Repeat(",?", rv.Len()-1)
@ -450,19 +460,19 @@ func handleArguments(query string, args []interface{}) (newQuery string, newArgs
}
// formatError customizes and returns the SQL error.
func formatError(err error, query string, args ...interface{}) error {
if err != nil && err != sql.ErrNoRows {
return errors.New(fmt.Sprintf("%s, %s\n", err.Error(), bindArgsToQuery(query, args)))
func formatError(err error, sql string, args ...interface{}) error {
if err != nil && err != ErrNoRows {
return errors.New(fmt.Sprintf("%s, %s\n", err.Error(), FormatSqlWithArgs(sql, args)))
}
return err
}
// bindArgsToQuery binds the arguments to the query string and returns a complete
// FormatSqlWithArgs binds the arguments to the sql string and returns a complete
// sql string, just for debugging.
func bindArgsToQuery(query string, args []interface{}) string {
func FormatSqlWithArgs(sql string, args []interface{}) string {
index := -1
newQuery, _ := gregex.ReplaceStringFunc(
`(\?|:\d+|\$\d+|@p\d+)`, query, func(s string) string {
`(\?|:\d+|\$\d+|@p\d+)`, sql, func(s string) string {
index++
if len(args) > index {
if args[index] == nil {

View File

@ -145,19 +145,19 @@ func (m *Model) ForPage(page, limit int) *Model {
}
// getAll does the query from database.
func (m *Model) getAll(query string, args ...interface{}) (result Result, err error) {
func (m *Model) getAll(sql string, args ...interface{}) (result Result, err error) {
cacheKey := ""
// Retrieve from cache.
if m.cacheEnabled {
cacheKey = m.cacheName
if len(cacheKey) == 0 {
cacheKey = query + "/" + gconv.String(args)
cacheKey = sql + "/" + gconv.String(args)
}
if v := m.db.GetCache().Get(cacheKey); v != nil {
return v.(Result), nil
}
}
result, err = m.db.DoGetAll(m.getLink(false), query, m.mergeArguments(args)...)
result, err = m.db.DoGetAll(m.getLink(false), sql, m.mergeArguments(args)...)
// Cache the result.
if len(cacheKey) > 0 && err == nil {
if m.cacheDuration < 0 {

View File

@ -67,8 +67,21 @@ func (m *Model) Data(data ...interface{}) *Model {
list[i] = DataToMapDeep(rv.Index(i).Interface())
}
model.data = list
case reflect.Map, reflect.Struct:
case reflect.Map:
model.data = DataToMapDeep(data[0])
case reflect.Struct:
if v, ok := data[0].(apiMapStrAny); ok {
model.data = v.MapStrAny()
} else if v, ok := data[0].(apiInterfaces); ok {
array := v.Interfaces()
list := make(List, len(array))
for i := 0; i < len(array); i++ {
list[i] = DataToMapDeep(array[i])
}
model.data = list
} else {
model.data = DataToMapDeep(data[0])
}
default:
model.data = data[0]
}

View File

@ -8,9 +8,11 @@ package gdb
import (
"fmt"
"github.com/gogf/gf/container/gmap"
"github.com/gogf/gf/container/gset"
"github.com/gogf/gf/internal/empty"
"github.com/gogf/gf/os/gtime"
"github.com/gogf/gf/text/gstr"
"time"
)
// getModel creates and returns a cloned model of current model if <safe> is true, or else it returns
@ -45,9 +47,25 @@ func (m *Model) doFilterDataMapForInsertOrUpdate(data Map, allowOmitEmpty bool)
}
// Remove key-value pairs of which the value is empty.
if allowOmitEmpty && m.option&OPTION_OMITEMPTY > 0 {
m := gmap.NewStrAnyMapFrom(data)
m.FilterEmpty()
data = m.Map()
tempMap := make(Map, len(data))
for k, v := range data {
if empty.IsEmpty(v) {
continue
}
// Special type filtering.
switch r := v.(type) {
case time.Time:
if r.IsZero() {
continue
}
case gtime.Time:
if r.IsZero() {
continue
}
}
tempMap[k] = v
}
data = tempMap
}
if len(m.fields) > 0 && m.fields != "*" {

View File

@ -33,14 +33,14 @@ func (tx *TX) Rollback() error {
// Query does query operation on transaction.
// See Core.Query.
func (tx *TX) Query(query string, args ...interface{}) (rows *sql.Rows, err error) {
return tx.db.DoQuery(tx.tx, query, args...)
func (tx *TX) Query(sql string, args ...interface{}) (rows *sql.Rows, err error) {
return tx.db.DoQuery(tx.tx, sql, args...)
}
// Exec does none query operation on transaction.
// See Core.Exec.
func (tx *TX) Exec(query string, args ...interface{}) (sql.Result, error) {
return tx.db.DoExec(tx.tx, query, args...)
func (tx *TX) Exec(sql string, args ...interface{}) (sql.Result, error) {
return tx.db.DoExec(tx.tx, sql, args...)
}
// Prepare creates a prepared statement for later queries or executions.
@ -48,13 +48,13 @@ func (tx *TX) Exec(query string, args ...interface{}) (sql.Result, error) {
// returned statement.
// The caller must call the statement's Close method
// when the statement is no longer needed.
func (tx *TX) Prepare(query string) (*sql.Stmt, error) {
return tx.db.DoPrepare(tx.tx, query)
func (tx *TX) Prepare(sql string) (*sql.Stmt, error) {
return tx.db.DoPrepare(tx.tx, sql)
}
// GetAll queries and returns data records from database.
func (tx *TX) GetAll(query string, args ...interface{}) (Result, error) {
rows, err := tx.Query(query, args...)
func (tx *TX) GetAll(sql string, args ...interface{}) (Result, error) {
rows, err := tx.Query(sql, args...)
if err != nil || rows == nil {
return nil, err
}
@ -63,8 +63,8 @@ func (tx *TX) GetAll(query string, args ...interface{}) (Result, error) {
}
// GetOne queries and returns one record from database.
func (tx *TX) GetOne(query string, args ...interface{}) (Record, error) {
list, err := tx.GetAll(query, args...)
func (tx *TX) GetOne(sql string, args ...interface{}) (Record, error) {
list, err := tx.GetAll(sql, args...)
if err != nil {
return nil, err
}
@ -76,8 +76,8 @@ func (tx *TX) GetOne(query string, args ...interface{}) (Record, error) {
// GetStruct queries one record from database and converts it to given struct.
// The parameter <pointer> should be a pointer to struct.
func (tx *TX) GetStruct(obj interface{}, query string, args ...interface{}) error {
one, err := tx.GetOne(query, args...)
func (tx *TX) GetStruct(obj interface{}, sql string, args ...interface{}) error {
one, err := tx.GetOne(sql, args...)
if err != nil {
return err
}
@ -86,8 +86,8 @@ func (tx *TX) GetStruct(obj interface{}, query string, args ...interface{}) erro
// GetStructs queries records from database and converts them to given struct.
// The parameter <pointer> should be type of struct slice: []struct/[]*struct.
func (tx *TX) GetStructs(objPointerSlice interface{}, query string, args ...interface{}) error {
all, err := tx.GetAll(query, args...)
func (tx *TX) GetStructs(objPointerSlice interface{}, sql string, args ...interface{}) error {
all, err := tx.GetAll(sql, args...)
if err != nil {
return err
}
@ -100,7 +100,7 @@ func (tx *TX) GetStructs(objPointerSlice interface{}, query string, args ...inte
// If parameter <pointer> is type of struct pointer, it calls GetStruct internally for
// the conversion. If parameter <pointer> is type of slice, it calls GetStructs internally
// for conversion.
func (tx *TX) GetScan(objPointer interface{}, query string, args ...interface{}) error {
func (tx *TX) GetScan(objPointer interface{}, sql string, args ...interface{}) error {
t := reflect.TypeOf(objPointer)
k := t.Kind()
if k != reflect.Ptr {
@ -109,9 +109,9 @@ func (tx *TX) GetScan(objPointer interface{}, query string, args ...interface{})
k = t.Elem().Kind()
switch k {
case reflect.Array, reflect.Slice:
return tx.db.GetStructs(objPointer, query, args...)
return tx.db.GetStructs(objPointer, sql, args...)
case reflect.Struct:
return tx.db.GetStruct(objPointer, query, args...)
return tx.db.GetStruct(objPointer, sql, args...)
default:
return fmt.Errorf("element type should be type of struct/slice, unsupported: %v", k)
}
@ -121,8 +121,8 @@ func (tx *TX) GetScan(objPointer interface{}, query string, args ...interface{})
// GetValue queries and returns the field value from database.
// The sql should queries only one field from database, or else it returns only one
// field of the result.
func (tx *TX) GetValue(query string, args ...interface{}) (Value, error) {
one, err := tx.GetOne(query, args...)
func (tx *TX) GetValue(sql string, args ...interface{}) (Value, error) {
one, err := tx.GetOne(sql, args...)
if err != nil {
return nil, err
}
@ -133,11 +133,11 @@ func (tx *TX) GetValue(query string, args ...interface{}) (Value, error) {
}
// GetCount queries and returns the count from database.
func (tx *TX) GetCount(query string, args ...interface{}) (int, error) {
if !gregex.IsMatchString(`(?i)SELECT\s+COUNT\(.+\)\s+FROM`, query) {
query, _ = gregex.ReplaceString(`(?i)(SELECT)\s+(.+)\s+(FROM)`, `$1 COUNT($2) $3`, query)
func (tx *TX) GetCount(sql string, args ...interface{}) (int, error) {
if !gregex.IsMatchString(`(?i)SELECT\s+COUNT\(.+\)\s+FROM`, sql) {
sql, _ = gregex.ReplaceString(`(?i)(SELECT)\s+(.+)\s+(FROM)`, `$1 COUNT($2) $3`, sql)
}
value, err := tx.GetValue(query, args...)
value, err := tx.GetValue(sql, args...)
if err != nil {
return 0, err
}

View File

@ -63,12 +63,12 @@ func Test_Custom_Driver(t *testing.T) {
Role: "master",
Charset: "utf8",
})
gtest.Case(t, func() {
gtest.Assert(latestSqlString.Val(), "")
gtest.C(t, func(t *gtest.T) {
t.Assert(latestSqlString.Val(), "")
sqlString := "select 10000"
value, err := g.DB("driver-test").GetValue(sqlString)
gtest.Assert(err, nil)
gtest.Assert(value, 10000)
gtest.Assert(latestSqlString.Val(), sqlString)
t.Assert(err, nil)
t.Assert(value, 10000)
t.Assert(latestSqlString.Val(), sqlString)
})
}

View File

@ -11,35 +11,35 @@ import (
"testing"
)
func Test_Func_bindArgsToQuery(t *testing.T) {
func Test_Func_FormatSqlWithArgs(t *testing.T) {
// mysql
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var s string
s = bindArgsToQuery("select * from table where id>=? and sex=?", []interface{}{100, 1})
gtest.Assert(s, "select * from table where id>=100 and sex=1")
s = FormatSqlWithArgs("select * from table where id>=? and sex=?", []interface{}{100, 1})
t.Assert(s, "select * from table where id>=100 and sex=1")
})
// mssql
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var s string
s = bindArgsToQuery("select * from table where id>=@p1 and sex=@p2", []interface{}{100, 1})
gtest.Assert(s, "select * from table where id>=100 and sex=1")
s = FormatSqlWithArgs("select * from table where id>=@p1 and sex=@p2", []interface{}{100, 1})
t.Assert(s, "select * from table where id>=100 and sex=1")
})
// pgsql
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var s string
s = bindArgsToQuery("select * from table where id>=$1 and sex=$2", []interface{}{100, 1})
gtest.Assert(s, "select * from table where id>=100 and sex=1")
s = FormatSqlWithArgs("select * from table where id>=$1 and sex=$2", []interface{}{100, 1})
t.Assert(s, "select * from table where id>=100 and sex=1")
})
// oracle
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var s string
s = bindArgsToQuery("select * from table where id>=:1 and sex=:2", []interface{}{100, 1})
gtest.Assert(s, "select * from table where id>=100 and sex=1")
s = FormatSqlWithArgs("select * from table where id>=:1 and sex=:2", []interface{}{100, 1})
t.Assert(s, "select * from table where id>=100 and sex=1")
})
}
func Test_Func_doQuoteWord(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
array := map[string]string{
"user": "`user`",
"user u": "user u",
@ -50,13 +50,13 @@ func Test_Func_doQuoteWord(t *testing.T) {
"u.id asc, ut.uid desc": "u.id asc, ut.uid desc",
}
for k, v := range array {
gtest.Assert(doQuoteWord(k, "`", "`"), v)
t.Assert(doQuoteWord(k, "`", "`"), v)
}
})
}
func Test_Func_doQuoteString(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
// "user", "user u", "user,user_detail", "user u, user_detail ut", "u.id asc".
array := map[string]string{
"user": "`user`",
@ -70,13 +70,13 @@ func Test_Func_doQuoteString(t *testing.T) {
"user..user u, user.user_detail ut": "`user`..`user` u,`user`.`user_detail` ut",
}
for k, v := range array {
gtest.Assert(doQuoteString(k, "`", "`"), v)
t.Assert(doQuoteString(k, "`", "`"), v)
}
})
}
func Test_Func_addTablePrefix(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
prefix := ""
array := map[string]string{
"user": "`user`",
@ -84,16 +84,18 @@ func Test_Func_addTablePrefix(t *testing.T) {
"user as u": "`user` as u",
"user,user_detail": "`user`,`user_detail`",
"user u, user_detail ut": "`user` u,`user_detail` ut",
"`user`.user_detail": "`user`.`user_detail`",
"`user`.`user_detail`": "`user`.`user_detail`",
"user as u, user_detail as ut": "`user` as u,`user_detail` as ut",
"UserCenter.user as u, UserCenter.user_detail as ut": "`UserCenter`.`user` as u,`UserCenter`.`user_detail` as ut",
// mssql global schema access with double dots.
"UserCenter..user as u, user_detail as ut": "`UserCenter`..`user` as u,`user_detail` as ut",
}
for k, v := range array {
gtest.Assert(doHandleTableName(k, prefix, "`", "`"), v)
t.Assert(doHandleTableName(k, prefix, "`", "`"), v)
}
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
prefix := "gf_"
array := map[string]string{
"user": "`gf_user`",
@ -101,13 +103,15 @@ func Test_Func_addTablePrefix(t *testing.T) {
"user as u": "`gf_user` as u",
"user,user_detail": "`gf_user`,`gf_user_detail`",
"user u, user_detail ut": "`gf_user` u,`gf_user_detail` ut",
"`user`.user_detail": "`user`.`gf_user_detail`",
"`user`.`user_detail`": "`user`.`gf_user_detail`",
"user as u, user_detail as ut": "`gf_user` as u,`gf_user_detail` as ut",
"UserCenter.user as u, UserCenter.user_detail as ut": "`UserCenter`.`gf_user` as u,`UserCenter`.`gf_user_detail` as ut",
// mssql global schema access with double dots.
"UserCenter..user as u, user_detail as ut": "`UserCenter`..`gf_user` as u,`gf_user_detail` as ut",
}
for k, v := range array {
gtest.Assert(doHandleTableName(k, prefix, "`", "`"), v)
t.Assert(doHandleTableName(k, prefix, "`", "`"), v)
}
})
}

View File

@ -14,16 +14,16 @@ import (
)
func Test_Instance(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
_, err := gdb.Instance("none")
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
db, err := gdb.Instance()
gtest.Assert(err, nil)
t.Assert(err, nil)
err1 := db.PingMaster()
err2 := db.PingSlave()
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
t.Assert(err1, nil)
t.Assert(err2, nil)
})
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ func Test_Model_Inherit_Insert(t *testing.T) {
table := createTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
type Base struct {
Id int `json:"id"`
Uid int `json:"uid"`
@ -40,12 +40,12 @@ func Test_Model_Inherit_Insert(t *testing.T) {
CreateTime: gtime.Now().String(),
},
}).Insert()
gtest.Assert(err, nil)
t.Assert(err, nil)
n, _ := result.RowsAffected()
gtest.Assert(n, 1)
t.Assert(n, 1)
value, err := db.Table(table).Fields("passport").Where("id=100").Value()
gtest.Assert(err, nil)
gtest.Assert(value.String(), "john-test")
t.Assert(err, nil)
t.Assert(value.String(), "john-test")
})
}
@ -53,7 +53,7 @@ func Test_Model_Inherit_MapToStruct(t *testing.T) {
table := createTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
type Ids struct {
Id int `json:"id"`
Uid int `json:"uid"`
@ -77,21 +77,21 @@ func Test_Model_Inherit_MapToStruct(t *testing.T) {
"create_time": gtime.Now().String(),
}
result, err := db.Table(table).Filter().Data(data).Insert()
gtest.Assert(err, nil)
t.Assert(err, nil)
n, _ := result.RowsAffected()
gtest.Assert(n, 1)
t.Assert(n, 1)
one, err := db.Table(table).Where("id=100").One()
gtest.Assert(err, nil)
t.Assert(err, nil)
user := new(User)
gtest.Assert(one.Struct(user), nil)
gtest.Assert(user.Id, data["id"])
gtest.Assert(user.Passport, data["passport"])
gtest.Assert(user.Password, data["password"])
gtest.Assert(user.Nickname, data["nickname"])
gtest.Assert(user.CreateTime, data["create_time"])
t.Assert(one.Struct(user), nil)
t.Assert(user.Id, data["id"])
t.Assert(user.Passport, data["passport"])
t.Assert(user.Password, data["password"])
t.Assert(user.Nickname, data["nickname"])
t.Assert(user.CreateTime, data["create_time"])
})

View File

@ -115,7 +115,7 @@ func Test_TX_Insert(t *testing.T) {
table := createTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -144,7 +144,7 @@ func Test_TX_Insert(t *testing.T) {
if n, err := tx.Table(table).Count(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(n, 2)
t.Assert(n, 2)
}
if err := tx.Commit(); err != nil {
@ -158,7 +158,7 @@ func Test_TX_BatchInsert(t *testing.T) {
table := createTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -187,7 +187,7 @@ func Test_TX_BatchInsert(t *testing.T) {
if n, err := db.Table(table).Count(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(n, 2)
t.Assert(n, 2)
}
})
}
@ -196,7 +196,7 @@ func Test_TX_BatchReplace(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -225,12 +225,12 @@ func Test_TX_BatchReplace(t *testing.T) {
if n, err := db.Table(table).Count(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(n, SIZE)
t.Assert(n, SIZE)
}
if value, err := db.Table(table).Fields("password").Where("id", 2).Value(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(value.String(), "PASS_2")
t.Assert(value.String(), "PASS_2")
}
})
}
@ -239,7 +239,7 @@ func Test_TX_BatchSave(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -262,13 +262,13 @@ func Test_TX_BatchSave(t *testing.T) {
if n, err := db.Table(table).Count(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(n, SIZE)
t.Assert(n, SIZE)
}
if value, err := db.Table(table).Fields("password").Where("id", 4).Value(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(value.String(), "PASS_4")
t.Assert(value.String(), "PASS_4")
}
})
}
@ -277,7 +277,7 @@ func Test_TX_Replace(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -297,7 +297,7 @@ func Test_TX_Replace(t *testing.T) {
if value, err := db.Table(table).Fields("nickname").Where("id", 1).Value(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(value.String(), "name_1")
t.Assert(value.String(), "name_1")
}
})
@ -307,7 +307,7 @@ func Test_TX_Save(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -327,7 +327,7 @@ func Test_TX_Save(t *testing.T) {
if value, err := db.Table(table).Fields("nickname").Where("id", 1).Value(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(value.String(), "NAME_1")
t.Assert(value.String(), "NAME_1")
}
})
}
@ -336,7 +336,7 @@ func Test_TX_Update(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -345,18 +345,18 @@ func Test_TX_Update(t *testing.T) {
gtest.Error(err)
} else {
n, _ := result.RowsAffected()
gtest.Assert(n, 1)
t.Assert(n, 1)
}
if err := tx.Commit(); err != nil {
gtest.Error(err)
}
_, err = tx.Table(table).Fields("create_time").Where("id", 3).Value()
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
if value, err := db.Table(table).Fields("create_time").Where("id", 3).Value(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(value.String(), "2019-10-24 10:00:00")
t.Assert(value.String(), "2019-10-24 10:00:00")
}
})
}
@ -365,7 +365,7 @@ func Test_TX_GetAll(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -373,7 +373,7 @@ func Test_TX_GetAll(t *testing.T) {
if result, err := tx.GetAll(fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 1); err != nil {
gtest.Error(err)
} else {
gtest.Assert(len(result), 1)
t.Assert(len(result), 1)
}
if err := tx.Commit(); err != nil {
gtest.Error(err)
@ -385,7 +385,7 @@ func Test_TX_GetOne(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -396,7 +396,7 @@ func Test_TX_GetOne(t *testing.T) {
if record == nil {
gtest.Error("FAIL")
}
gtest.Assert(record["nickname"].String(), "name_2")
t.Assert(record["nickname"].String(), "name_2")
}
if err := tx.Commit(); err != nil {
gtest.Error(err)
@ -408,7 +408,7 @@ func Test_TX_GetValue(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -416,7 +416,7 @@ func Test_TX_GetValue(t *testing.T) {
if value, err := tx.GetValue(fmt.Sprintf("SELECT id FROM %s WHERE passport=?", table), "user_3"); err != nil {
gtest.Error(err)
} else {
gtest.Assert(value.Int(), 3)
t.Assert(value.Int(), 3)
}
if err := tx.Commit(); err != nil {
gtest.Error(err)
@ -429,7 +429,7 @@ func Test_TX_GetCount(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -437,7 +437,7 @@ func Test_TX_GetCount(t *testing.T) {
if count, err := tx.GetCount("SELECT * FROM " + table); err != nil {
gtest.Error(err)
} else {
gtest.Assert(count, SIZE)
t.Assert(count, SIZE)
}
if err := tx.Commit(); err != nil {
gtest.Error(err)
@ -449,7 +449,7 @@ func Test_TX_GetStruct(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -465,13 +465,13 @@ func Test_TX_GetStruct(t *testing.T) {
if err := tx.GetStruct(user, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 3); err != nil {
gtest.Error(err)
}
gtest.Assert(user.NickName, "name_3")
gtest.Assert(user.CreateTime.String(), "2018-10-24 10:00:00")
t.Assert(user.NickName, "name_3")
t.Assert(user.CreateTime.String(), "2018-10-24 10:00:00")
if err := tx.Commit(); err != nil {
gtest.Error(err)
}
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -487,8 +487,8 @@ func Test_TX_GetStruct(t *testing.T) {
if err := tx.GetStruct(user, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 3); err != nil {
gtest.Error(err)
}
gtest.Assert(user.NickName, "name_3")
gtest.Assert(user.CreateTime.String(), "2018-10-24 10:00:00")
t.Assert(user.NickName, "name_3")
t.Assert(user.CreateTime.String(), "2018-10-24 10:00:00")
if err := tx.Commit(); err != nil {
gtest.Error(err)
}
@ -499,7 +499,7 @@ func Test_TX_GetStructs(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -515,20 +515,20 @@ func Test_TX_GetStructs(t *testing.T) {
if err := tx.GetStructs(&users, fmt.Sprintf("SELECT * FROM %s WHERE id>=?", table), 1); err != nil {
gtest.Error(err)
}
gtest.Assert(len(users), SIZE)
gtest.Assert(users[0].Id, 1)
gtest.Assert(users[1].Id, 2)
gtest.Assert(users[2].Id, 3)
gtest.Assert(users[0].NickName, "name_1")
gtest.Assert(users[1].NickName, "name_2")
gtest.Assert(users[2].NickName, "name_3")
gtest.Assert(users[2].CreateTime.String(), "2018-10-24 10:00:00")
t.Assert(len(users), SIZE)
t.Assert(users[0].Id, 1)
t.Assert(users[1].Id, 2)
t.Assert(users[2].Id, 3)
t.Assert(users[0].NickName, "name_1")
t.Assert(users[1].NickName, "name_2")
t.Assert(users[2].NickName, "name_3")
t.Assert(users[2].CreateTime.String(), "2018-10-24 10:00:00")
if err := tx.Commit(); err != nil {
gtest.Error(err)
}
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -544,14 +544,14 @@ func Test_TX_GetStructs(t *testing.T) {
if err := tx.GetStructs(&users, fmt.Sprintf("SELECT * FROM %s WHERE id>=?", table), 1); err != nil {
gtest.Error(err)
}
gtest.Assert(len(users), SIZE)
gtest.Assert(users[0].Id, 1)
gtest.Assert(users[1].Id, 2)
gtest.Assert(users[2].Id, 3)
gtest.Assert(users[0].NickName, "name_1")
gtest.Assert(users[1].NickName, "name_2")
gtest.Assert(users[2].NickName, "name_3")
gtest.Assert(users[2].CreateTime.String(), "2018-10-24 10:00:00")
t.Assert(len(users), SIZE)
t.Assert(users[0].Id, 1)
t.Assert(users[1].Id, 2)
t.Assert(users[2].Id, 3)
t.Assert(users[0].NickName, "name_1")
t.Assert(users[1].NickName, "name_2")
t.Assert(users[2].NickName, "name_3")
t.Assert(users[2].CreateTime.String(), "2018-10-24 10:00:00")
if err := tx.Commit(); err != nil {
gtest.Error(err)
}
@ -562,7 +562,7 @@ func Test_TX_GetScan(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -578,13 +578,13 @@ func Test_TX_GetScan(t *testing.T) {
if err := tx.GetScan(user, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 3); err != nil {
gtest.Error(err)
}
gtest.Assert(user.NickName, "name_3")
gtest.Assert(user.CreateTime.String(), "2018-10-24 10:00:00")
t.Assert(user.NickName, "name_3")
t.Assert(user.CreateTime.String(), "2018-10-24 10:00:00")
if err := tx.Commit(); err != nil {
gtest.Error(err)
}
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -600,14 +600,14 @@ func Test_TX_GetScan(t *testing.T) {
if err := tx.GetScan(user, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 3); err != nil {
gtest.Error(err)
}
gtest.Assert(user.NickName, "name_3")
gtest.Assert(user.CreateTime.String(), "2018-10-24 10:00:00")
t.Assert(user.NickName, "name_3")
t.Assert(user.CreateTime.String(), "2018-10-24 10:00:00")
if err := tx.Commit(); err != nil {
gtest.Error(err)
}
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -623,20 +623,20 @@ func Test_TX_GetScan(t *testing.T) {
if err := tx.GetScan(&users, fmt.Sprintf("SELECT * FROM %s WHERE id>=?", table), 1); err != nil {
gtest.Error(err)
}
gtest.Assert(len(users), SIZE)
gtest.Assert(users[0].Id, 1)
gtest.Assert(users[1].Id, 2)
gtest.Assert(users[2].Id, 3)
gtest.Assert(users[0].NickName, "name_1")
gtest.Assert(users[1].NickName, "name_2")
gtest.Assert(users[2].NickName, "name_3")
gtest.Assert(users[2].CreateTime.String(), "2018-10-24 10:00:00")
t.Assert(len(users), SIZE)
t.Assert(users[0].Id, 1)
t.Assert(users[1].Id, 2)
t.Assert(users[2].Id, 3)
t.Assert(users[0].NickName, "name_1")
t.Assert(users[1].NickName, "name_2")
t.Assert(users[2].NickName, "name_3")
t.Assert(users[2].CreateTime.String(), "2018-10-24 10:00:00")
if err := tx.Commit(); err != nil {
gtest.Error(err)
}
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
tx, err := db.Begin()
if err != nil {
gtest.Error(err)
@ -652,14 +652,14 @@ func Test_TX_GetScan(t *testing.T) {
if err := tx.GetScan(&users, fmt.Sprintf("SELECT * FROM %s WHERE id>=?", table), 1); err != nil {
gtest.Error(err)
}
gtest.Assert(len(users), SIZE)
gtest.Assert(users[0].Id, 1)
gtest.Assert(users[1].Id, 2)
gtest.Assert(users[2].Id, 3)
gtest.Assert(users[0].NickName, "name_1")
gtest.Assert(users[1].NickName, "name_2")
gtest.Assert(users[2].NickName, "name_3")
gtest.Assert(users[2].CreateTime.String(), "2018-10-24 10:00:00")
t.Assert(len(users), SIZE)
t.Assert(users[0].Id, 1)
t.Assert(users[1].Id, 2)
t.Assert(users[2].Id, 3)
t.Assert(users[0].NickName, "name_1")
t.Assert(users[1].NickName, "name_2")
t.Assert(users[2].NickName, "name_3")
t.Assert(users[2].CreateTime.String(), "2018-10-24 10:00:00")
if err := tx.Commit(); err != nil {
gtest.Error(err)
}
@ -668,7 +668,7 @@ func Test_TX_GetScan(t *testing.T) {
func Test_TX_Delete(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
table := createInitTable()
defer dropTable(table)
tx, err := db.Begin()
@ -684,11 +684,11 @@ func Test_TX_Delete(t *testing.T) {
if n, err := db.Table(table).Count(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(n, 0)
t.Assert(n, 0)
}
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
table := createInitTable()
defer dropTable(table)
tx, err := db.Begin()
@ -701,7 +701,7 @@ func Test_TX_Delete(t *testing.T) {
if n, err := tx.Table(table).Count(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(n, 0)
t.Assert(n, 0)
}
if err := tx.Rollback(); err != nil {
gtest.Error(err)
@ -709,8 +709,8 @@ func Test_TX_Delete(t *testing.T) {
if n, err := db.Table(table).Count(); err != nil {
gtest.Error(err)
} else {
gtest.Assert(n, SIZE)
gtest.AssertNE(n, 0)
t.Assert(n, SIZE)
t.AssertNE(n, 0)
}
})

View File

@ -17,7 +17,7 @@ import (
func Test_Types(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
if _, err := db.Exec(fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS types (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
@ -50,21 +50,21 @@ func Test_Types(t *testing.T) {
"bool": false,
}
r, err := db.Table("types").Data(data).Insert()
gtest.Assert(err, nil)
t.Assert(err, nil)
n, _ := r.RowsAffected()
gtest.Assert(n, 1)
t.Assert(n, 1)
one, err := db.Table("types").One()
gtest.Assert(err, nil)
gtest.Assert(one["id"].Int(), 1)
gtest.Assert(one["blob"].String(), data["blob"])
gtest.Assert(one["binary"].String(), data["binary"])
gtest.Assert(one["date"].String(), data["date"])
gtest.Assert(one["time"].String(), data["time"])
gtest.Assert(one["decimal"].String(), -123.46)
gtest.Assert(one["double"].String(), data["double"])
gtest.Assert(one["bit"].Int(), data["bit"])
gtest.Assert(one["tinyint"].Bool(), data["tinyint"])
gtest.Assert(one["tinyint"].Bool(), data["tinyint"])
t.Assert(err, nil)
t.Assert(one["id"].Int(), 1)
t.Assert(one["blob"].String(), data["blob"])
t.Assert(one["binary"].String(), data["binary"])
t.Assert(one["date"].String(), data["date"])
t.Assert(one["time"].String(), data["time"])
t.Assert(one["decimal"].String(), -123.46)
t.Assert(one["double"].String(), data["double"])
t.Assert(one["bit"].Int(), data["bit"])
t.Assert(one["tinyint"].Bool(), data["tinyint"])
t.Assert(one["tinyint"].Bool(), data["tinyint"])
})
}

View File

@ -29,35 +29,35 @@ var (
)
func Test_NewClose(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
redis := gredis.New(config)
gtest.AssertNE(redis, nil)
t.AssertNE(redis, nil)
err := redis.Close()
gtest.Assert(err, nil)
t.Assert(err, nil)
})
}
func Test_Do(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
redis := gredis.New(config)
defer redis.Close()
_, err := redis.Do("SET", "k", "v")
gtest.Assert(err, nil)
t.Assert(err, nil)
r, err := redis.Do("GET", "k")
gtest.Assert(err, nil)
gtest.Assert(r, []byte("v"))
t.Assert(err, nil)
t.Assert(r, []byte("v"))
_, err = redis.Do("DEL", "k")
gtest.Assert(err, nil)
t.Assert(err, nil)
r, err = redis.Do("GET", "k")
gtest.Assert(err, nil)
gtest.Assert(r, nil)
t.Assert(err, nil)
t.Assert(r, nil)
})
}
func Test_Stats(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
redis := gredis.New(config)
defer redis.Close()
redis.SetMaxIdle(2)
@ -70,24 +70,24 @@ func Test_Stats(t *testing.T) {
array = append(array, redis.Conn())
}
stats := redis.Stats()
gtest.Assert(stats.ActiveCount, 10)
gtest.Assert(stats.IdleCount, 0)
t.Assert(stats.ActiveCount, 10)
t.Assert(stats.IdleCount, 0)
for i := 0; i < 10; i++ {
array[i].Close()
}
stats = redis.Stats()
gtest.Assert(stats.ActiveCount, 2)
gtest.Assert(stats.IdleCount, 2)
t.Assert(stats.ActiveCount, 2)
t.Assert(stats.IdleCount, 2)
//time.Sleep(3000*time.Millisecond)
//stats = redis.Stats()
//fmt.Println(stats)
//gtest.Assert(stats.ActiveCount, 0)
//gtest.Assert(stats.IdleCount, 0)
//t.Assert(stats.ActiveCount, 0)
//t.Assert(stats.IdleCount, 0)
})
}
func Test_Conn(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
redis := gredis.New(config)
defer redis.Close()
conn := redis.Conn()
@ -96,22 +96,22 @@ func Test_Conn(t *testing.T) {
key := gconv.String(gtime.TimestampNano())
value := []byte("v")
r, err := conn.Do("SET", key, value)
gtest.Assert(err, nil)
t.Assert(err, nil)
r, err = conn.Do("GET", key)
gtest.Assert(err, nil)
gtest.Assert(r, value)
t.Assert(err, nil)
t.Assert(r, value)
_, err = conn.Do("DEL", key)
gtest.Assert(err, nil)
t.Assert(err, nil)
r, err = conn.Do("GET", key)
gtest.Assert(err, nil)
gtest.Assert(r, nil)
t.Assert(err, nil)
t.Assert(r, nil)
})
}
func Test_Instance(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
group := "my-test"
gredis.SetConfig(config, group)
defer gredis.RemoveConfig(group)
@ -122,22 +122,22 @@ func Test_Instance(t *testing.T) {
defer conn.Close()
_, err := conn.Do("SET", "k", "v")
gtest.Assert(err, nil)
t.Assert(err, nil)
r, err := conn.Do("GET", "k")
gtest.Assert(err, nil)
gtest.Assert(r, []byte("v"))
t.Assert(err, nil)
t.Assert(r, []byte("v"))
_, err = conn.Do("DEL", "k")
gtest.Assert(err, nil)
t.Assert(err, nil)
r, err = conn.Do("GET", "k")
gtest.Assert(err, nil)
gtest.Assert(r, nil)
t.Assert(err, nil)
t.Assert(r, nil)
})
}
func Test_Error(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
config1 := gredis.Config{
Host: "127.0.0.2",
Port: 6379,
@ -146,7 +146,7 @@ func Test_Error(t *testing.T) {
}
redis := gredis.New(config1)
_, err := redis.Do("info")
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
config1 = gredis.Config{
Host: "127.0.0.1",
@ -156,7 +156,7 @@ func Test_Error(t *testing.T) {
}
redis = gredis.New(config1)
_, err = redis.Do("info")
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
config1 = gredis.Config{
Host: "127.0.0.1",
@ -165,28 +165,28 @@ func Test_Error(t *testing.T) {
}
redis = gredis.New(config1)
_, err = redis.Do("info")
gtest.AssertNE(err, nil)
t.AssertNE(err, nil)
redis = gredis.Instance("gf")
gtest.Assert(redis == nil, true)
t.Assert(redis == nil, true)
gredis.ClearConfig()
redis = gredis.New(config)
defer redis.Close()
_, err = redis.DoVar("SET", "k", "v")
gtest.Assert(err, nil)
t.Assert(err, nil)
v, err := redis.DoVar("GET", "k")
gtest.Assert(err, nil)
gtest.Assert(v.String(), "v")
t.Assert(err, nil)
t.Assert(v.String(), "v")
conn := redis.GetConn()
_, err = conn.DoVar("SET", "k", "v")
gtest.Assert(err, nil)
t.Assert(err, nil)
//v, err = conn.ReceiveVar()
//gtest.Assert(err, nil)
//gtest.Assert(v.String(), "v")
//t.Assert(err, nil)
//t.Assert(v.String(), "v")
psc := redis2.PubSubConn{Conn: conn}
psc.Subscribe("gf")
@ -196,7 +196,7 @@ func Test_Error(t *testing.T) {
v, _ := conn.ReceiveVar()
switch obj := v.Val().(type) {
case redis2.Message:
gtest.Assert(string(obj.Data), "gf test")
t.Assert(string(obj.Data), "gf test")
case redis2.Subscription:
}
@ -208,7 +208,7 @@ func Test_Error(t *testing.T) {
}
func Test_Bool(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
redis := gredis.New(config)
defer func() {
redis.Do("DEL", "key-true")
@ -216,66 +216,66 @@ func Test_Bool(t *testing.T) {
}()
_, err := redis.Do("SET", "key-true", true)
gtest.Assert(err, nil)
t.Assert(err, nil)
_, err = redis.Do("SET", "key-false", false)
gtest.Assert(err, nil)
t.Assert(err, nil)
r, err := redis.DoVar("GET", "key-true")
gtest.Assert(err, nil)
gtest.Assert(r.Bool(), true)
t.Assert(err, nil)
t.Assert(r.Bool(), true)
r, err = redis.DoVar("GET", "key-false")
gtest.Assert(err, nil)
gtest.Assert(r.Bool(), false)
t.Assert(err, nil)
t.Assert(r.Bool(), false)
})
}
func Test_Int(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
redis := gredis.New(config)
key := guuid.New()
defer redis.Do("DEL", key)
_, err := redis.Do("SET", key, 1)
gtest.Assert(err, nil)
t.Assert(err, nil)
r, err := redis.DoVar("GET", key)
gtest.Assert(err, nil)
gtest.Assert(r.Int(), 1)
t.Assert(err, nil)
t.Assert(r.Int(), 1)
})
}
func Test_HSet(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
redis := gredis.New(config)
key := guuid.New()
defer redis.Do("DEL", key)
_, err := redis.Do("HSET", key, "name", "john")
gtest.Assert(err, nil)
t.Assert(err, nil)
r, err := redis.DoVar("HGETALL", key)
gtest.Assert(err, nil)
gtest.Assert(r.Strings(), g.ArrayStr{"name", "john"})
t.Assert(err, nil)
t.Assert(r.Strings(), g.ArrayStr{"name", "john"})
})
}
func Test_HGetAll(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
var err error
redis := gredis.New(config)
key := guuid.New()
defer redis.Do("DEL", key)
_, err = redis.Do("HSET", key, "id", "100")
gtest.Assert(err, nil)
t.Assert(err, nil)
_, err = redis.Do("HSET", key, "name", "john")
gtest.Assert(err, nil)
t.Assert(err, nil)
r, err := redis.DoVar("HGETALL", key)
gtest.Assert(err, nil)
gtest.Assert(r.Map(), g.MapStrAny{
t.Assert(err, nil)
t.Assert(r.Map(), g.MapStrAny{
"id": 100,
"name": "john",
})

View File

@ -10,8 +10,14 @@ import (
"path/filepath"
)
// TestDataPath retrieves and returns the testdata path of current package.
// It is used for unit testing cases only.
func TestDataPath() string {
return CallerDirectory() + string(filepath.Separator) + "testdata"
// TestDataPath retrieves and returns the testdata path of current package,
// which is used for unit testing cases only.
// The optional parameter <names> specifies the its sub-folders/sub-files,
// which will be joined with current system separator and returned with the path.
func TestDataPath(names ...string) string {
path := CallerDirectory() + string(filepath.Separator) + "testdata"
for _, name := range names {
path += string(filepath.Separator) + name
}
return path
}

View File

@ -8,7 +8,6 @@ package gbase64_test
import (
"github.com/gogf/gf/debug/gdebug"
"github.com/gogf/gf/os/gfile"
"testing"
"github.com/gogf/gf/encoding/gbase64"
@ -46,52 +45,52 @@ var pairs = []testPair{
}
func Test_Basic(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
for k := range pairs {
// Encode
gtest.Assert(gbase64.Encode([]byte(pairs[k].decoded)), []byte(pairs[k].encoded))
gtest.Assert(gbase64.EncodeToString([]byte(pairs[k].decoded)), pairs[k].encoded)
gtest.Assert(gbase64.EncodeString(pairs[k].decoded), pairs[k].encoded)
t.Assert(gbase64.Encode([]byte(pairs[k].decoded)), []byte(pairs[k].encoded))
t.Assert(gbase64.EncodeToString([]byte(pairs[k].decoded)), pairs[k].encoded)
t.Assert(gbase64.EncodeString(pairs[k].decoded), pairs[k].encoded)
// Decode
r1, _ := gbase64.Decode([]byte(pairs[k].encoded))
gtest.Assert(r1, []byte(pairs[k].decoded))
t.Assert(r1, []byte(pairs[k].decoded))
r2, _ := gbase64.DecodeString(pairs[k].encoded)
gtest.Assert(r2, []byte(pairs[k].decoded))
t.Assert(r2, []byte(pairs[k].decoded))
r3, _ := gbase64.DecodeToString(pairs[k].encoded)
gtest.Assert(r3, pairs[k].decoded)
t.Assert(r3, pairs[k].decoded)
}
})
}
func Test_File(t *testing.T) {
path := gfile.Join(gdebug.TestDataPath(), "test")
path := gdebug.TestDataPath("test")
expect := "dGVzdA=="
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
b, err := gbase64.EncodeFile(path)
gtest.Assert(err, nil)
gtest.Assert(string(b), expect)
t.Assert(err, nil)
t.Assert(string(b), expect)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s, err := gbase64.EncodeFileToString(path)
gtest.Assert(err, nil)
gtest.Assert(s, expect)
t.Assert(err, nil)
t.Assert(s, expect)
})
}
func Test_File_Error(t *testing.T) {
path := "none-exist-file"
expect := ""
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
b, err := gbase64.EncodeFile(path)
gtest.AssertNE(err, nil)
gtest.Assert(string(b), expect)
t.AssertNE(err, nil)
t.Assert(string(b), expect)
})
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
s, err := gbase64.EncodeFileToString(path)
gtest.AssertNE(err, nil)
gtest.Assert(s, expect)
t.AssertNE(err, nil)
t.Assert(s, expect)
})
}

View File

@ -14,71 +14,75 @@ import (
)
func Test_BeEncodeAndBeDecode(t *testing.T) {
for k, v := range testData {
ve := gbinary.BeEncode(v)
ve1 := gbinary.BeEncodeByLength(len(ve), v)
gtest.C(t, func(t *gtest.T) {
for k, v := range testData {
ve := gbinary.BeEncode(v)
ve1 := gbinary.BeEncodeByLength(len(ve), v)
//t.Logf("%s:%v, encoded:%v\n", k, v, ve)
switch v.(type) {
case int:
gtest.Assert(gbinary.BeDecodeToInt(ve), v)
gtest.Assert(gbinary.BeDecodeToInt(ve1), v)
case int8:
gtest.Assert(gbinary.BeDecodeToInt8(ve), v)
gtest.Assert(gbinary.BeDecodeToInt8(ve1), v)
case int16:
gtest.Assert(gbinary.BeDecodeToInt16(ve), v)
gtest.Assert(gbinary.BeDecodeToInt16(ve1), v)
case int32:
gtest.Assert(gbinary.BeDecodeToInt32(ve), v)
gtest.Assert(gbinary.BeDecodeToInt32(ve1), v)
case int64:
gtest.Assert(gbinary.BeDecodeToInt64(ve), v)
gtest.Assert(gbinary.BeDecodeToInt64(ve1), v)
case uint:
gtest.Assert(gbinary.BeDecodeToUint(ve), v)
gtest.Assert(gbinary.BeDecodeToUint(ve1), v)
case uint8:
gtest.Assert(gbinary.BeDecodeToUint8(ve), v)
gtest.Assert(gbinary.BeDecodeToUint8(ve1), v)
case uint16:
gtest.Assert(gbinary.BeDecodeToUint16(ve1), v)
gtest.Assert(gbinary.BeDecodeToUint16(ve), v)
case uint32:
gtest.Assert(gbinary.BeDecodeToUint32(ve1), v)
gtest.Assert(gbinary.BeDecodeToUint32(ve), v)
case uint64:
gtest.Assert(gbinary.BeDecodeToUint64(ve), v)
gtest.Assert(gbinary.BeDecodeToUint64(ve1), v)
case bool:
gtest.Assert(gbinary.BeDecodeToBool(ve), v)
gtest.Assert(gbinary.BeDecodeToBool(ve1), v)
case string:
gtest.Assert(gbinary.BeDecodeToString(ve), v)
gtest.Assert(gbinary.BeDecodeToString(ve1), v)
case float32:
gtest.Assert(gbinary.BeDecodeToFloat32(ve), v)
gtest.Assert(gbinary.BeDecodeToFloat32(ve1), v)
case float64:
gtest.Assert(gbinary.BeDecodeToFloat64(ve), v)
gtest.Assert(gbinary.BeDecodeToFloat64(ve1), v)
default:
if v == nil {
continue
//t.Logf("%s:%v, encoded:%v\n", k, v, ve)
switch v.(type) {
case int:
t.Assert(gbinary.BeDecodeToInt(ve), v)
t.Assert(gbinary.BeDecodeToInt(ve1), v)
case int8:
t.Assert(gbinary.BeDecodeToInt8(ve), v)
t.Assert(gbinary.BeDecodeToInt8(ve1), v)
case int16:
t.Assert(gbinary.BeDecodeToInt16(ve), v)
t.Assert(gbinary.BeDecodeToInt16(ve1), v)
case int32:
t.Assert(gbinary.BeDecodeToInt32(ve), v)
t.Assert(gbinary.BeDecodeToInt32(ve1), v)
case int64:
t.Assert(gbinary.BeDecodeToInt64(ve), v)
t.Assert(gbinary.BeDecodeToInt64(ve1), v)
case uint:
t.Assert(gbinary.BeDecodeToUint(ve), v)
t.Assert(gbinary.BeDecodeToUint(ve1), v)
case uint8:
t.Assert(gbinary.BeDecodeToUint8(ve), v)
t.Assert(gbinary.BeDecodeToUint8(ve1), v)
case uint16:
t.Assert(gbinary.BeDecodeToUint16(ve1), v)
t.Assert(gbinary.BeDecodeToUint16(ve), v)
case uint32:
t.Assert(gbinary.BeDecodeToUint32(ve1), v)
t.Assert(gbinary.BeDecodeToUint32(ve), v)
case uint64:
t.Assert(gbinary.BeDecodeToUint64(ve), v)
t.Assert(gbinary.BeDecodeToUint64(ve1), v)
case bool:
t.Assert(gbinary.BeDecodeToBool(ve), v)
t.Assert(gbinary.BeDecodeToBool(ve1), v)
case string:
t.Assert(gbinary.BeDecodeToString(ve), v)
t.Assert(gbinary.BeDecodeToString(ve1), v)
case float32:
t.Assert(gbinary.BeDecodeToFloat32(ve), v)
t.Assert(gbinary.BeDecodeToFloat32(ve1), v)
case float64:
t.Assert(gbinary.BeDecodeToFloat64(ve), v)
t.Assert(gbinary.BeDecodeToFloat64(ve1), v)
default:
if v == nil {
continue
}
res := make([]byte, len(ve))
err := gbinary.BeDecode(ve, res)
if err != nil {
t.Errorf("test data: %s, %v, error:%v", k, v, err)
}
t.Assert(res, v)
}
res := make([]byte, len(ve))
err := gbinary.BeDecode(ve, res)
if err != nil {
t.Errorf("test data: %s, %v, error:%v", k, v, err)
}
gtest.Assert(res, v)
}
}
})
}
func Test_BeEncodeStruct(t *testing.T) {
user := User{"wenzi1", 999, "www.baidu.com"}
ve := gbinary.BeEncode(user)
s := gbinary.BeDecodeToString(ve)
gtest.Assert(string(s), s)
gtest.C(t, func(t *gtest.T) {
user := User{"wenzi1", 999, "www.baidu.com"}
ve := gbinary.BeEncode(user)
s := gbinary.BeDecodeToString(ve)
t.Assert(string(s), s)
})
}

View File

@ -14,71 +14,75 @@ import (
)
func Test_LeEncodeAndLeDecode(t *testing.T) {
for k, v := range testData {
ve := gbinary.LeEncode(v)
ve1 := gbinary.LeEncodeByLength(len(ve), v)
gtest.C(t, func(t *gtest.T) {
for k, v := range testData {
ve := gbinary.LeEncode(v)
ve1 := gbinary.LeEncodeByLength(len(ve), v)
//t.Logf("%s:%v, encoded:%v\n", k, v, ve)
switch v.(type) {
case int:
gtest.Assert(gbinary.LeDecodeToInt(ve), v)
gtest.Assert(gbinary.LeDecodeToInt(ve1), v)
case int8:
gtest.Assert(gbinary.LeDecodeToInt8(ve), v)
gtest.Assert(gbinary.LeDecodeToInt8(ve1), v)
case int16:
gtest.Assert(gbinary.LeDecodeToInt16(ve), v)
gtest.Assert(gbinary.LeDecodeToInt16(ve1), v)
case int32:
gtest.Assert(gbinary.LeDecodeToInt32(ve), v)
gtest.Assert(gbinary.LeDecodeToInt32(ve1), v)
case int64:
gtest.Assert(gbinary.LeDecodeToInt64(ve), v)
gtest.Assert(gbinary.LeDecodeToInt64(ve1), v)
case uint:
gtest.Assert(gbinary.LeDecodeToUint(ve), v)
gtest.Assert(gbinary.LeDecodeToUint(ve1), v)
case uint8:
gtest.Assert(gbinary.LeDecodeToUint8(ve), v)
gtest.Assert(gbinary.LeDecodeToUint8(ve1), v)
case uint16:
gtest.Assert(gbinary.LeDecodeToUint16(ve1), v)
gtest.Assert(gbinary.LeDecodeToUint16(ve), v)
case uint32:
gtest.Assert(gbinary.LeDecodeToUint32(ve1), v)
gtest.Assert(gbinary.LeDecodeToUint32(ve), v)
case uint64:
gtest.Assert(gbinary.LeDecodeToUint64(ve), v)
gtest.Assert(gbinary.LeDecodeToUint64(ve1), v)
case bool:
gtest.Assert(gbinary.LeDecodeToBool(ve), v)
gtest.Assert(gbinary.LeDecodeToBool(ve1), v)
case string:
gtest.Assert(gbinary.LeDecodeToString(ve), v)
gtest.Assert(gbinary.LeDecodeToString(ve1), v)
case float32:
gtest.Assert(gbinary.LeDecodeToFloat32(ve), v)
gtest.Assert(gbinary.LeDecodeToFloat32(ve1), v)
case float64:
gtest.Assert(gbinary.LeDecodeToFloat64(ve), v)
gtest.Assert(gbinary.LeDecodeToFloat64(ve1), v)
default:
if v == nil {
continue
//t.Logf("%s:%v, encoded:%v\n", k, v, ve)
switch v.(type) {
case int:
t.Assert(gbinary.LeDecodeToInt(ve), v)
t.Assert(gbinary.LeDecodeToInt(ve1), v)
case int8:
t.Assert(gbinary.LeDecodeToInt8(ve), v)
t.Assert(gbinary.LeDecodeToInt8(ve1), v)
case int16:
t.Assert(gbinary.LeDecodeToInt16(ve), v)
t.Assert(gbinary.LeDecodeToInt16(ve1), v)
case int32:
t.Assert(gbinary.LeDecodeToInt32(ve), v)
t.Assert(gbinary.LeDecodeToInt32(ve1), v)
case int64:
t.Assert(gbinary.LeDecodeToInt64(ve), v)
t.Assert(gbinary.LeDecodeToInt64(ve1), v)
case uint:
t.Assert(gbinary.LeDecodeToUint(ve), v)
t.Assert(gbinary.LeDecodeToUint(ve1), v)
case uint8:
t.Assert(gbinary.LeDecodeToUint8(ve), v)
t.Assert(gbinary.LeDecodeToUint8(ve1), v)
case uint16:
t.Assert(gbinary.LeDecodeToUint16(ve1), v)
t.Assert(gbinary.LeDecodeToUint16(ve), v)
case uint32:
t.Assert(gbinary.LeDecodeToUint32(ve1), v)
t.Assert(gbinary.LeDecodeToUint32(ve), v)
case uint64:
t.Assert(gbinary.LeDecodeToUint64(ve), v)
t.Assert(gbinary.LeDecodeToUint64(ve1), v)
case bool:
t.Assert(gbinary.LeDecodeToBool(ve), v)
t.Assert(gbinary.LeDecodeToBool(ve1), v)
case string:
t.Assert(gbinary.LeDecodeToString(ve), v)
t.Assert(gbinary.LeDecodeToString(ve1), v)
case float32:
t.Assert(gbinary.LeDecodeToFloat32(ve), v)
t.Assert(gbinary.LeDecodeToFloat32(ve1), v)
case float64:
t.Assert(gbinary.LeDecodeToFloat64(ve), v)
t.Assert(gbinary.LeDecodeToFloat64(ve1), v)
default:
if v == nil {
continue
}
res := make([]byte, len(ve))
err := gbinary.LeDecode(ve, res)
if err != nil {
t.Errorf("test data: %s, %v, error:%v", k, v, err)
}
t.Assert(res, v)
}
res := make([]byte, len(ve))
err := gbinary.LeDecode(ve, res)
if err != nil {
t.Errorf("test data: %s, %v, error:%v", k, v, err)
}
gtest.Assert(res, v)
}
}
})
}
func Test_LeEncodeStruct(t *testing.T) {
user := User{"wenzi1", 999, "www.baidu.com"}
ve := gbinary.LeEncode(user)
s := gbinary.LeDecodeToString(ve)
gtest.Assert(string(s), s)
gtest.C(t, func(t *gtest.T) {
user := User{"wenzi1", 999, "www.baidu.com"}
ve := gbinary.LeEncode(user)
s := gbinary.LeDecodeToString(ve)
t.Assert(s, s)
})
}

View File

@ -49,84 +49,89 @@ var testData = map[string]interface{}{
var testBitData = []int{0, 99, 122, 129, 222, 999, 22322}
func Test_EncodeAndDecode(t *testing.T) {
for k, v := range testData {
ve := gbinary.Encode(v)
ve1 := gbinary.EncodeByLength(len(ve), v)
gtest.C(t, func(t *gtest.T) {
for k, v := range testData {
ve := gbinary.Encode(v)
ve1 := gbinary.EncodeByLength(len(ve), v)
//t.Logf("%s:%v, encoded:%v\n", k, v, ve)
switch v.(type) {
case int:
gtest.Assert(gbinary.DecodeToInt(ve), v)
gtest.Assert(gbinary.DecodeToInt(ve1), v)
case int8:
gtest.Assert(gbinary.DecodeToInt8(ve), v)
gtest.Assert(gbinary.DecodeToInt8(ve1), v)
case int16:
gtest.Assert(gbinary.DecodeToInt16(ve), v)
gtest.Assert(gbinary.DecodeToInt16(ve1), v)
case int32:
gtest.Assert(gbinary.DecodeToInt32(ve), v)
gtest.Assert(gbinary.DecodeToInt32(ve1), v)
case int64:
gtest.Assert(gbinary.DecodeToInt64(ve), v)
gtest.Assert(gbinary.DecodeToInt64(ve1), v)
case uint:
gtest.Assert(gbinary.DecodeToUint(ve), v)
gtest.Assert(gbinary.DecodeToUint(ve1), v)
case uint8:
gtest.Assert(gbinary.DecodeToUint8(ve), v)
gtest.Assert(gbinary.DecodeToUint8(ve1), v)
case uint16:
gtest.Assert(gbinary.DecodeToUint16(ve1), v)
gtest.Assert(gbinary.DecodeToUint16(ve), v)
case uint32:
gtest.Assert(gbinary.DecodeToUint32(ve1), v)
gtest.Assert(gbinary.DecodeToUint32(ve), v)
case uint64:
gtest.Assert(gbinary.DecodeToUint64(ve), v)
gtest.Assert(gbinary.DecodeToUint64(ve1), v)
case bool:
gtest.Assert(gbinary.DecodeToBool(ve), v)
gtest.Assert(gbinary.DecodeToBool(ve1), v)
case string:
gtest.Assert(gbinary.DecodeToString(ve), v)
gtest.Assert(gbinary.DecodeToString(ve1), v)
case float32:
gtest.Assert(gbinary.DecodeToFloat32(ve), v)
gtest.Assert(gbinary.DecodeToFloat32(ve1), v)
case float64:
gtest.Assert(gbinary.DecodeToFloat64(ve), v)
gtest.Assert(gbinary.DecodeToFloat64(ve1), v)
default:
if v == nil {
continue
//t.Logf("%s:%v, encoded:%v\n", k, v, ve)
switch v.(type) {
case int:
t.Assert(gbinary.DecodeToInt(ve), v)
t.Assert(gbinary.DecodeToInt(ve1), v)
case int8:
t.Assert(gbinary.DecodeToInt8(ve), v)
t.Assert(gbinary.DecodeToInt8(ve1), v)
case int16:
t.Assert(gbinary.DecodeToInt16(ve), v)
t.Assert(gbinary.DecodeToInt16(ve1), v)
case int32:
t.Assert(gbinary.DecodeToInt32(ve), v)
t.Assert(gbinary.DecodeToInt32(ve1), v)
case int64:
t.Assert(gbinary.DecodeToInt64(ve), v)
t.Assert(gbinary.DecodeToInt64(ve1), v)
case uint:
t.Assert(gbinary.DecodeToUint(ve), v)
t.Assert(gbinary.DecodeToUint(ve1), v)
case uint8:
t.Assert(gbinary.DecodeToUint8(ve), v)
t.Assert(gbinary.DecodeToUint8(ve1), v)
case uint16:
t.Assert(gbinary.DecodeToUint16(ve1), v)
t.Assert(gbinary.DecodeToUint16(ve), v)
case uint32:
t.Assert(gbinary.DecodeToUint32(ve1), v)
t.Assert(gbinary.DecodeToUint32(ve), v)
case uint64:
t.Assert(gbinary.DecodeToUint64(ve), v)
t.Assert(gbinary.DecodeToUint64(ve1), v)
case bool:
t.Assert(gbinary.DecodeToBool(ve), v)
t.Assert(gbinary.DecodeToBool(ve1), v)
case string:
t.Assert(gbinary.DecodeToString(ve), v)
t.Assert(gbinary.DecodeToString(ve1), v)
case float32:
t.Assert(gbinary.DecodeToFloat32(ve), v)
t.Assert(gbinary.DecodeToFloat32(ve1), v)
case float64:
t.Assert(gbinary.DecodeToFloat64(ve), v)
t.Assert(gbinary.DecodeToFloat64(ve1), v)
default:
if v == nil {
continue
}
res := make([]byte, len(ve))
err := gbinary.Decode(ve, res)
if err != nil {
t.Errorf("test data: %s, %v, error:%v", k, v, err)
}
t.Assert(res, v)
}
res := make([]byte, len(ve))
err := gbinary.Decode(ve, res)
if err != nil {
t.Errorf("test data: %s, %v, error:%v", k, v, err)
}
gtest.Assert(res, v)
}
}
})
}
func Test_EncodeStruct(t *testing.T) {
user := User{"wenzi1", 999, "www.baidu.com"}
ve := gbinary.Encode(user)
s := gbinary.DecodeToString(ve)
gtest.Assert(string(s), s)
gtest.C(t, func(t *gtest.T) {
user := User{"wenzi1", 999, "www.baidu.com"}
ve := gbinary.Encode(user)
s := gbinary.DecodeToString(ve)
t.Assert(s, s)
})
}
func Test_Bits(t *testing.T) {
for i := range testBitData {
bits := make([]gbinary.Bit, 0)
res := gbinary.EncodeBits(bits, testBitData[i], 64)
gtest.C(t, func(t *gtest.T) {
for i := range testBitData {
bits := make([]gbinary.Bit, 0)
res := gbinary.EncodeBits(bits, testBitData[i], 64)
gtest.Assert(gbinary.DecodeBits(res), testBitData[i])
gtest.Assert(gbinary.DecodeBitsToUint(res), uint(testBitData[i]))
gtest.Assert(gbinary.DecodeBytesToBits(gbinary.EncodeBitsToBytes(res)), res)
}
t.Assert(gbinary.DecodeBits(res), testBitData[i])
t.Assert(gbinary.DecodeBitsToUint(res), uint(testBitData[i]))
t.Assert(gbinary.DecodeBytesToBits(gbinary.EncodeBitsToBytes(res)), res)
}
})
}

View File

@ -138,28 +138,28 @@ func TestConvert(t *testing.T) {
}
func TestConvertErr(t *testing.T) {
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
srcCharset := "big5"
dstCharset := "gbk"
src := "Hello \xb1`\xa5\u03b0\xea\xa6r\xbc\u0437\u01e6r\xc5\xe9\xaa\xed"
s1, e1 := gcharset.Convert(srcCharset, srcCharset, src)
gtest.Assert(e1, nil)
gtest.Assert(s1, src)
t.Assert(e1, nil)
t.Assert(s1, src)
s2, e2 := gcharset.Convert(dstCharset, "no this charset", src)
gtest.AssertNE(e2, nil)
gtest.Assert(s2, src)
t.AssertNE(e2, nil)
t.Assert(s2, src)
s3, e3 := gcharset.Convert("no this charset", srcCharset, src)
gtest.AssertNE(e3, nil)
gtest.Assert(s3, src)
t.AssertNE(e3, nil)
t.Assert(s3, src)
})
}
func TestSupported(t *testing.T) {
gtest.Case(t, func() {
gtest.Assert(gcharset.Supported("UTF-8"), true)
gtest.Assert(gcharset.Supported("UTF-80"), false)
gtest.C(t, func(t *gtest.T) {
t.Assert(gcharset.Supported("UTF-8"), true)
t.Assert(gcharset.Supported("UTF-80"), false)
})
}

View File

@ -29,37 +29,37 @@ func Test_Gzip_UnGzip(t *testing.T) {
0x24, 0xa8, 0xd1, 0x0d, 0x00,
0x00, 0x00,
}
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
arr := []byte(src)
data, _ := gcompress.Gzip(arr)
gtest.Assert(data, gzip)
t.Assert(data, gzip)
data, _ = gcompress.UnGzip(gzip)
gtest.Assert(data, arr)
t.Assert(data, arr)
data, _ = gcompress.UnGzip(gzip[1:])
gtest.Assert(data, nil)
t.Assert(data, nil)
})
}
func Test_Gzip_UnGzip_File(t *testing.T) {
srcPath := gfile.Join(gdebug.TestDataPath(), "gzip", "file.txt")
dstPath1 := gfile.Join(gfile.TempDir(), gtime.TimestampNanoStr(), "gzip.zip")
dstPath2 := gfile.Join(gfile.TempDir(), gtime.TimestampNanoStr(), "file.txt")
srcPath := gdebug.TestDataPath("gzip", "file.txt")
dstPath1 := gfile.TempDir(gtime.TimestampNanoStr(), "gzip.zip")
dstPath2 := gfile.TempDir(gtime.TimestampNanoStr(), "file.txt")
// Compress.
gtest.Case(t, func() {
gtest.C(t, func(t *gtest.T) {
err := gcompress.GzipFile(srcPath, dstPath1, 9)
gtest.Assert(err, nil)
t.Assert(err, nil)
defer gfile.Remove(dstPath1)
gtest.Assert(gfile.Exists(dstPath1), true)
t.Assert(gfile.Exists(dstPath1), true)
// Decompress.
err = gcompress.UnGzipFile(dstPath1, dstPath2)
gtest.Assert(err, nil)
t.Assert(err, nil)
defer gfile.Remove(dstPath2)
gtest.Assert(gfile.Exists(dstPath2), true)
t.Assert(gfile.Exists(dstPath2), true)
gtest.Assert(gfile.GetContents(srcPath), gfile.GetContents(dstPath2))
t.Assert(gfile.GetContents(srcPath), gfile.GetContents(dstPath2))
})
}

View File

@ -19,95 +19,95 @@ import (
func Test_ZipPath(t *testing.T) {
// file
gtest.Case(t, func() {
srcPath := gfile.Join(gdebug.TestDataPath(), "zip", "path1", "1.txt")
dstPath := gfile.Join(gdebug.TestDataPath(), "zip", "zip.zip")
gtest.C(t, func(t *gtest.T) {
srcPath := gdebug.TestDataPath("zip", "path1", "1.txt")
dstPath := gdebug.TestDataPath("zip", "zip.zip")
gtest.Assert(gfile.Exists(dstPath), false)
t.Assert(gfile.Exists(dstPath), false)
err := gcompress.ZipPath(srcPath, dstPath)
gtest.Assert(err, nil)
gtest.Assert(gfile.Exists(dstPath), true)
t.Assert(err, nil)
t.Assert(gfile.Exists(dstPath), true)
defer gfile.Remove(dstPath)
tempDirPath := gfile.Join(gfile.TempDir(), gtime.TimestampNanoStr())
tempDirPath := gfile.TempDir(gtime.TimestampNanoStr())
err = gfile.Mkdir(tempDirPath)
gtest.Assert(err, nil)
t.Assert(err, nil)
err = gcompress.UnZipFile(dstPath, tempDirPath)
gtest.Assert(err, nil)
t.Assert(err, nil)
defer gfile.Remove(tempDirPath)
gtest.Assert(
t.Assert(
gfile.GetContents(gfile.Join(tempDirPath, "1.txt")),
gfile.GetContents(gfile.Join(srcPath, "path1", "1.txt")),
)
})
// directory
gtest.Case(t, func() {
srcPath := gfile.Join(gdebug.TestDataPath(), "zip")
dstPath := gfile.Join(gdebug.TestDataPath(), "zip", "zip.zip")
gtest.C(t, func(t *gtest.T) {
srcPath := gdebug.TestDataPath("zip")
dstPath := gdebug.TestDataPath("zip", "zip.zip")
pwd := gfile.Pwd()
err := gfile.Chdir(srcPath)
defer gfile.Chdir(pwd)
gtest.Assert(err, nil)
t.Assert(err, nil)
gtest.Assert(gfile.Exists(dstPath), false)
t.Assert(gfile.Exists(dstPath), false)
err = gcompress.ZipPath(srcPath, dstPath)
gtest.Assert(err, nil)
gtest.Assert(gfile.Exists(dstPath), true)
t.Assert(err, nil)
t.Assert(gfile.Exists(dstPath), true)
defer gfile.Remove(dstPath)
tempDirPath := gfile.Join(gfile.TempDir(), gtime.TimestampNanoStr())
tempDirPath := gfile.TempDir(gtime.TimestampNanoStr())
err = gfile.Mkdir(tempDirPath)
gtest.Assert(err, nil)
t.Assert(err, nil)
err = gcompress.UnZipFile(dstPath, tempDirPath)
gtest.Assert(err, nil)
t.Assert(err, nil)
defer gfile.Remove(tempDirPath)
gtest.Assert(
t.Assert(
gfile.GetContents(gfile.Join(tempDirPath, "zip", "path1", "1.txt")),
gfile.GetContents(gfile.Join(srcPath, "path1", "1.txt")),
)
gtest.Assert(
t.Assert(
gfile.GetContents(gfile.Join(tempDirPath, "zip", "path2", "2.txt")),
gfile.GetContents(gfile.Join(srcPath, "path2", "2.txt")),
)
})
// multiple paths joined using char ','
gtest.Case(t, func() {
srcPath := gfile.Join(gdebug.TestDataPath(), "zip")
srcPath1 := gfile.Join(gdebug.TestDataPath(), "zip", "path1")
srcPath2 := gfile.Join(gdebug.TestDataPath(), "zip", "path2")
dstPath := gfile.Join(gdebug.TestDataPath(), "zip", "zip.zip")
gtest.C(t, func(t *gtest.T) {
srcPath := gdebug.TestDataPath("zip")
srcPath1 := gdebug.TestDataPath("zip", "path1")
srcPath2 := gdebug.TestDataPath("zip", "path2")
dstPath := gdebug.TestDataPath("zip", "zip.zip")
pwd := gfile.Pwd()
err := gfile.Chdir(srcPath)
defer gfile.Chdir(pwd)
gtest.Assert(err, nil)
t.Assert(err, nil)
gtest.Assert(gfile.Exists(dstPath), false)
t.Assert(gfile.Exists(dstPath), false)
err = gcompress.ZipPath(srcPath1+", "+srcPath2, dstPath)
gtest.Assert(err, nil)
gtest.Assert(gfile.Exists(dstPath), true)
t.Assert(err, nil)
t.Assert(gfile.Exists(dstPath), true)
defer gfile.Remove(dstPath)
tempDirPath := gfile.Join(gfile.TempDir(), gtime.TimestampNanoStr())
tempDirPath := gfile.TempDir(gtime.TimestampNanoStr())
err = gfile.Mkdir(tempDirPath)
gtest.Assert(err, nil)
t.Assert(err, nil)
zipContent := gfile.GetBytes(dstPath)
gtest.AssertGT(len(zipContent), 0)
t.AssertGT(len(zipContent), 0)
err = gcompress.UnZipContent(zipContent, tempDirPath)
gtest.Assert(err, nil)
t.Assert(err, nil)
defer gfile.Remove(tempDirPath)
gtest.Assert(
t.Assert(
gfile.GetContents(gfile.Join(tempDirPath, "path1", "1.txt")),
gfile.GetContents(gfile.Join(srcPath, "path1", "1.txt")),
)
gtest.Assert(
t.Assert(
gfile.GetContents(gfile.Join(tempDirPath, "path2", "2.txt")),
gfile.GetContents(gfile.Join(srcPath, "path2", "2.txt")),
)
@ -115,37 +115,37 @@ func Test_ZipPath(t *testing.T) {
}
func Test_ZipPathWriter(t *testing.T) {
gtest.Case(t, func() {
srcPath := gfile.Join(gdebug.TestDataPath(), "zip")
srcPath1 := gfile.Join(gdebug.TestDataPath(), "zip", "path1")
srcPath2 := gfile.Join(gdebug.TestDataPath(), "zip", "path2")
gtest.C(t, func(t *gtest.T) {
srcPath := gdebug.TestDataPath("zip")
srcPath1 := gdebug.TestDataPath("zip", "path1")
srcPath2 := gdebug.TestDataPath("zip", "path2")
pwd := gfile.Pwd()
err := gfile.Chdir(srcPath)
defer gfile.Chdir(pwd)
gtest.Assert(err, nil)
t.Assert(err, nil)
writer := bytes.NewBuffer(nil)
gtest.Assert(writer.Len(), 0)
t.Assert(writer.Len(), 0)
err = gcompress.ZipPathWriter(srcPath1+", "+srcPath2, writer)
gtest.Assert(err, nil)
gtest.AssertGT(writer.Len(), 0)
t.Assert(err, nil)
t.AssertGT(writer.Len(), 0)
tempDirPath := gfile.Join(gfile.TempDir(), gtime.TimestampNanoStr())
tempDirPath := gfile.TempDir(gtime.TimestampNanoStr())
err = gfile.Mkdir(tempDirPath)
gtest.Assert(err, nil)
t.Assert(err, nil)
zipContent := writer.Bytes()
gtest.AssertGT(len(zipContent), 0)
t.AssertGT(len(zipContent), 0)
err = gcompress.UnZipContent(zipContent, tempDirPath)
gtest.Assert(err, nil)
t.Assert(err, nil)
defer gfile.Remove(tempDirPath)
gtest.Assert(
t.Assert(
gfile.GetContents(gfile.Join(tempDirPath, "path1", "1.txt")),
gfile.GetContents(gfile.Join(srcPath, "path1", "1.txt")),
)
gtest.Assert(
t.Assert(
gfile.GetContents(gfile.Join(tempDirPath, "path2", "2.txt")),
gfile.GetContents(gfile.Join(srcPath, "path2", "2.txt")),
)

Some files were not shown because too many files have changed in this diff Show More