2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 13:47:15 +08:00

feat: add tests

This commit is contained in:
耗子
2023-06-23 04:20:57 +08:00
parent 5e4d02f2cc
commit 98a92da490
8 changed files with 299 additions and 154 deletions

View File

@@ -0,0 +1,42 @@
package captcha
import (
"testing"
"time"
testifymock "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
"github.com/goravel/framework/testing/mock"
)
type CaptchaTestSuite struct {
suite.Suite
captcha *Captcha
}
func TestCaptchaTestSuite(t *testing.T) {
mockConfig := mock.Config()
mockConfig.On("GetString", "app.name").Return("HaoZiPanel").Once()
mockConfig.On("GetInt", "captcha.height").Return(80).Once()
mockConfig.On("GetInt", "captcha.width").Return(240).Once()
mockConfig.On("GetInt", "captcha.length").Return(4).Once()
mockConfig.On("Get", "captcha.maxskew").Return(0.7).Once()
mockConfig.On("GetInt", "captcha.dotcount").Return(80).Once()
mockConfig.On("GetInt", "captcha.expire_time").Return(5).Once()
mockConfig.On("GetInt", "captcha.debug_expire_time").Return(10).Once()
mockConfig.On("GetBool", "app.debug").Return(true).Once()
mockCache, _, _ := mock.Cache()
mockCache.On("Put", testifymock.Anything, testifymock.Anything, time.Minute*time.Duration(10)).Return(nil).Once()
suite.Run(t, &CaptchaTestSuite{
captcha: NewCaptcha(),
})
mockConfig.AssertExpectations(t)
}
func (s *CaptchaTestSuite) TestGenerateCaptcha() {
id, base64, err := s.captcha.GenerateCaptcha()
s.NotEmpty(id)
s.NotEmpty(base64)
s.Nil(err)
}

View File

@@ -2,15 +2,8 @@
package helpers
import (
"crypto/md5"
"crypto/rand"
"fmt"
"io"
"os"
"reflect"
"strings"
"time"
"unicode/utf8"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/disk"
@@ -18,94 +11,8 @@ import (
"github.com/shirou/gopsutil/load"
"github.com/shirou/gopsutil/mem"
"github.com/shirou/gopsutil/net"
"github.com/shirou/gopsutil/process"
)
// Empty 类似于 PHP 的 empty() 函数
func Empty(val interface{}) bool {
if val == nil {
return true
}
v := reflect.ValueOf(val)
switch v.Kind() {
case reflect.String, reflect.Array:
return v.Len() == 0
case reflect.Map, reflect.Slice:
return v.Len() == 0 || v.IsNil()
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
}
return reflect.DeepEqual(val, reflect.Zero(v.Type()).Interface())
}
// FirstElement 安全地获取 args[0],避免 panic: runtime error: index out of range
func FirstElement(args []string) string {
if len(args) > 0 {
return args[0]
}
return ""
}
// RandomNumber 生成长度为 length 随机数字字符串
func RandomNumber(length int) string {
table := [...]byte{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}
b := make([]byte, length)
n, err := io.ReadAtLeast(rand.Reader, b, length)
if n != length {
panic(err)
}
for i := 0; i < len(b); i++ {
b[i] = table[int(b[i])%len(table)]
}
return string(b)
}
// RandomString 生成长度为 length 的随机字符串
func RandomString(length int) string {
b := make([]byte, length)
_, err := rand.Read(b)
if err != nil {
panic(err)
}
letters := "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i, v := range b {
b[i] = letters[v%byte(len(letters))]
}
return string(b)
}
// MD5 生成字符串的 MD5 值
func MD5(str string) string {
return fmt.Sprintf("%x", md5.Sum([]byte(str)))
}
// FormatBytes 格式化bytes
func FormatBytes(size float64) string {
units := []string{"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
i := 0
for ; size >= 1024 && i < len(units); i++ {
size /= 1024
}
return fmt.Sprintf("%.2f %s", size, units[i])
}
// Cut 裁剪字符串
func Cut(begin, end, str string) string {
b := utf8.RuneCountInString(str[:strings.Index(str, begin)]) + utf8.RuneCountInString(begin)
e := utf8.RuneCountInString(str[:strings.Index(str, end)]) - b
return string([]rune(str)[b : b+e])
}
// MonitoringInfo 监控信息
type MonitoringInfo struct {
Cpus []cpu.InfoStat `json:"cpus"`
@@ -118,7 +25,6 @@ type MonitoringInfo struct {
DiskIO map[string]disk.IOCountersStat `json:"disk_io"`
Disk []disk.PartitionStat `json:"disk"`
DiskUsage map[string]*disk.UsageStat `json:"disk_usage"`
Process []*process.Process `json:"process"`
}
// GetMonitoringInfo 获取监控数据
@@ -133,7 +39,6 @@ func GetMonitoringInfo() MonitoringInfo {
res.Net, _ = net.IOCounters(true)
res.DiskIO, _ = disk.IOCounters()
res.Disk, _ = disk.Partitions(true)
res.Process, _ = process.Processes()
res.DiskUsage = make(map[string]*disk.UsageStat)
for _, partition := range res.Disk {
@@ -146,15 +51,3 @@ func GetMonitoringInfo() MonitoringInfo {
return res
}
// IsDebian 判断是否是 Debian 系统
func IsDebian() bool {
_, err := os.Stat("/etc/debian_version")
return err == nil
}
// IsRHEL 判断是否是 RHEL 系统
func IsRHEL() bool {
_, err := os.Stat("/etc/redhat-release")
return err == nil
}

View File

@@ -14,51 +14,6 @@ func TestHelperTestSuite(t *testing.T) {
suite.Run(t, &HelperTestSuite{})
}
func (s *HelperTestSuite) TestEmpty() {
s.True(Empty(""))
s.True(Empty(nil))
s.True(Empty([]string{}))
s.True(Empty(map[string]string{}))
s.True(Empty(0))
s.True(Empty(0.0))
s.True(Empty(false))
s.False(Empty(" "))
s.False(Empty([]string{"Panel"}))
s.False(Empty(map[string]string{"Panel": "HaoZi"}))
s.False(Empty(1))
s.False(Empty(1.0))
s.False(Empty(true))
}
func (s *HelperTestSuite) TestFirstElement() {
s.Equal("HaoZi", FirstElement([]string{"HaoZi"}))
}
func (s *HelperTestSuite) TestRandomNumber() {
s.Len(RandomNumber(10), 10)
}
func (s *HelperTestSuite) TestRandomString() {
s.Len(RandomString(10), 10)
}
func (s *HelperTestSuite) TestMD5() {
s.Equal("e10adc3949ba59abbe56e057f20f883e", MD5("123456"))
}
func (s *HelperTestSuite) TestFormatBytes() {
s.Equal("1.00 B", FormatBytes(1))
s.Equal("1.00 KB", FormatBytes(1024))
s.Equal("1.00 MB", FormatBytes(1024*1024))
s.Equal("1.00 GB", FormatBytes(1024*1024*1024))
s.Equal("1.00 TB", FormatBytes(1024*1024*1024*1024))
s.Equal("1.00 PB", FormatBytes(1024*1024*1024*1024*1024))
s.Equal("1.00 EB", FormatBytes(1024*1024*1024*1024*1024*1024))
s.Equal("1.00 ZB", FormatBytes(1024*1024*1024*1024*1024*1024*1024))
s.Equal("1.00 YB", FormatBytes(1024*1024*1024*1024*1024*1024*1024*1024))
}
func (s *HelperTestSuite) TestCut() {
s.Equal("aoZ", Cut("H", "i", "HaoZi"))
func (s *HelperTestSuite) TestGetMonitoringInfo() {
s.NotNil(GetMonitoringInfo())
}

23
packages/helpers/os.go Normal file
View File

@@ -0,0 +1,23 @@
package helpers
import (
"os"
"runtime"
)
// IsDebian 判断是否是 Debian 系统
func IsDebian() bool {
_, err := os.Stat("/etc/debian_version")
return err == nil
}
// IsRHEL 判断是否是 RHEL 系统
func IsRHEL() bool {
_, err := os.Stat("/etc/redhat-release")
return err == nil
}
// IsArm 判断是否是 ARM 架构
func IsArm() bool {
return runtime.GOARCH == "arm"
}

View File

@@ -0,0 +1,27 @@
package helpers
import (
"testing"
"github.com/stretchr/testify/suite"
)
type OSHelperTestSuite struct {
suite.Suite
}
func TestOSHelperTestSuite(t *testing.T) {
suite.Run(t, &OSHelperTestSuite{})
}
func (s *OSHelperTestSuite) TestIsDebian() {
s.False(IsDebian())
}
func (s *OSHelperTestSuite) TestIsRHEL() {
s.False(IsRHEL())
}
func (s *OSHelperTestSuite) TestIsArm() {
s.False(IsArm())
}

View File

@@ -0,0 +1,96 @@
package helpers
import (
"crypto/md5"
"crypto/rand"
"fmt"
"io"
"reflect"
"strings"
"unicode/utf8"
)
// Empty 类似于 PHP 的 empty() 函数
func Empty(val interface{}) bool {
if val == nil {
return true
}
v := reflect.ValueOf(val)
switch v.Kind() {
case reflect.String, reflect.Array:
return v.Len() == 0
case reflect.Map, reflect.Slice:
return v.Len() == 0 || v.IsNil()
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
}
return reflect.DeepEqual(val, reflect.Zero(v.Type()).Interface())
}
// FirstElement 安全地获取 args[0],避免 panic: runtime error: index out of range
func FirstElement(args []string) string {
if len(args) > 0 {
return args[0]
}
return ""
}
// RandomNumber 生成长度为 length 随机数字字符串
func RandomNumber(length int) string {
table := [...]byte{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}
b := make([]byte, length)
n, err := io.ReadAtLeast(rand.Reader, b, length)
if n != length {
panic(err)
}
for i := 0; i < len(b); i++ {
b[i] = table[int(b[i])%len(table)]
}
return string(b)
}
// RandomString 生成长度为 length 的随机字符串
func RandomString(length int) string {
b := make([]byte, length)
_, err := rand.Read(b)
if err != nil {
panic(err)
}
letters := "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i, v := range b {
b[i] = letters[v%byte(len(letters))]
}
return string(b)
}
// MD5 生成字符串的 MD5 值
func MD5(str string) string {
return fmt.Sprintf("%x", md5.Sum([]byte(str)))
}
// FormatBytes 格式化bytes
func FormatBytes(size float64) string {
units := []string{"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
i := 0
for ; size >= 1024 && i < len(units); i++ {
size /= 1024
}
return fmt.Sprintf("%.2f %s", size, units[i])
}
// Cut 裁剪字符串
func Cut(begin, end, str string) string {
b := utf8.RuneCountInString(str[:strings.Index(str, begin)]) + utf8.RuneCountInString(begin)
e := utf8.RuneCountInString(str[:strings.Index(str, end)]) - b
return string([]rune(str)[b : b+e])
}

View File

@@ -0,0 +1,64 @@
package helpers
import (
"testing"
"github.com/stretchr/testify/suite"
)
type StringHelperTestSuite struct {
suite.Suite
}
func TestStringHelperTestSuite(t *testing.T) {
suite.Run(t, &StringHelperTestSuite{})
}
func (s *StringHelperTestSuite) TestEmpty() {
s.True(Empty(""))
s.True(Empty(nil))
s.True(Empty([]string{}))
s.True(Empty(map[string]string{}))
s.True(Empty(0))
s.True(Empty(0.0))
s.True(Empty(false))
s.False(Empty(" "))
s.False(Empty([]string{"Panel"}))
s.False(Empty(map[string]string{"Panel": "HaoZi"}))
s.False(Empty(1))
s.False(Empty(1.0))
s.False(Empty(true))
}
func (s *StringHelperTestSuite) TestFirstElement() {
s.Equal("HaoZi", FirstElement([]string{"HaoZi"}))
}
func (s *StringHelperTestSuite) TestRandomNumber() {
s.Len(RandomNumber(10), 10)
}
func (s *StringHelperTestSuite) TestRandomString() {
s.Len(RandomString(10), 10)
}
func (s *StringHelperTestSuite) TestMD5() {
s.Equal("e10adc3949ba59abbe56e057f20f883e", MD5("123456"))
}
func (s *StringHelperTestSuite) TestFormatBytes() {
s.Equal("1.00 B", FormatBytes(1))
s.Equal("1.00 KB", FormatBytes(1024))
s.Equal("1.00 MB", FormatBytes(1024*1024))
s.Equal("1.00 GB", FormatBytes(1024*1024*1024))
s.Equal("1.00 TB", FormatBytes(1024*1024*1024*1024))
s.Equal("1.00 PB", FormatBytes(1024*1024*1024*1024*1024))
s.Equal("1.00 EB", FormatBytes(1024*1024*1024*1024*1024*1024))
s.Equal("1.00 ZB", FormatBytes(1024*1024*1024*1024*1024*1024*1024))
s.Equal("1.00 YB", FormatBytes(1024*1024*1024*1024*1024*1024*1024*1024))
}
func (s *StringHelperTestSuite) TestCut() {
s.Equal("aoZ", Cut("H", "i", "HaoZi"))
}

45
packages/str/str_test.go Normal file
View File

@@ -0,0 +1,45 @@
package str
import (
"testing"
"github.com/stretchr/testify/suite"
)
type StrTestSuite struct {
suite.Suite
}
func TestStrTestSuite(t *testing.T) {
suite.Run(t, &StrTestSuite{})
}
func (s *StrTestSuite) TestPlural() {
s.Equal("users", Plural("user"))
s.Equal("users", Plural("users"))
}
func (s *StrTestSuite) TestSingular() {
s.Equal("user", Singular("users"))
s.Equal("user", Singular("user"))
}
func (s *StrTestSuite) TestSnake() {
s.Equal("topic_comment", Snake("TopicComment"))
s.Equal("topic_comment", Snake("topic_comment"))
}
func (s *StrTestSuite) TestCamel() {
s.Equal("TopicComment", Camel("topic_comment"))
s.Equal("TopicComment", Camel("TopicComment"))
}
func (s *StrTestSuite) TestLowerCamel() {
s.Equal("topicComment", LowerCamel("topic_comment"))
s.Equal("topicComment", LowerCamel("TopicComment"))
}
func (s *StrTestSuite) TestContainsString() {
s.True(ContainsString([]string{"a", "b", "c"}, "a"))
s.False(ContainsString([]string{"a", "b", "c"}, "d"))
}