Update to latest gomatrix. Things are broken
This commit is contained in:
parent
68db26bcac
commit
cfb2cc057c
40
Gopkg.lock
generated
40
Gopkg.lock
generated
@ -4,14 +4,14 @@
|
|||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/davecgh/go-spew"
|
name = "github.com/davecgh/go-spew"
|
||||||
packages = ["spew"]
|
packages = ["spew"]
|
||||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
|
||||||
version = "v1.1.0"
|
version = "v1.1.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/disintegration/imaging"
|
name = "github.com/disintegration/imaging"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "bbcee2f5c9d5e94ca42c8b50ec847fec64a6c134"
|
revision = "0bd5694c78c9c3d9a3cd06a706a8f3c59296a9ac"
|
||||||
version = "v1.4.2"
|
version = "v1.5.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -26,16 +26,16 @@
|
|||||||
version = "v1.5.1"
|
version = "v1.5.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
|
||||||
name = "github.com/lucasb-eyer/go-colorful"
|
name = "github.com/lucasb-eyer/go-colorful"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "8abd3beca3a7f5039809449d6013a0254ac22bb1"
|
revision = "345fbb3dbcdb252d9985ee899a84963c0fa24c82"
|
||||||
|
version = "v1.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/mattn/go-runewidth"
|
name = "github.com/mattn/go-runewidth"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "9e777a8366cce605130a531d2cd6363d07ad7317"
|
revision = "ce7b0b5c7b45a81508558cd1dba6bb1e4ddb51bb"
|
||||||
version = "v0.0.2"
|
version = "v0.0.3"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -50,10 +50,10 @@
|
|||||||
version = "v1.0.0"
|
version = "v1.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
|
||||||
name = "github.com/renstrom/fuzzysearch"
|
name = "github.com/renstrom/fuzzysearch"
|
||||||
packages = ["fuzzy"]
|
packages = ["fuzzy"]
|
||||||
revision = "500e0fce37a81072d9bf4ec1bf5d32f52c807282"
|
revision = "b18e754edff4833912ef4dce9eaca885bd3f0de1"
|
||||||
|
version = "v1.0.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -64,14 +64,14 @@
|
|||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/stretchr/testify"
|
name = "github.com/stretchr/testify"
|
||||||
packages = ["assert"]
|
packages = ["assert"]
|
||||||
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
|
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
|
||||||
version = "v1.2.1"
|
version = "v1.2.2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/zyedidia/clipboard"
|
name = "github.com/zyedidia/clipboard"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "4611e809d8b1a3051c11d11f4b610c44df73fa38"
|
revision = "bd31d747117d04b4e25b61f73e1ea4faeea3c56a"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -85,7 +85,7 @@
|
|||||||
"vp8l",
|
"vp8l",
|
||||||
"webp"
|
"webp"
|
||||||
]
|
]
|
||||||
revision = "f315e440302883054d0c2bd85486878cb4f8572c"
|
revision = "c73c2afc3b812cdd6385de5a50616511c4a3d458"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -94,7 +94,7 @@
|
|||||||
"html",
|
"html",
|
||||||
"html/atom"
|
"html/atom"
|
||||||
]
|
]
|
||||||
revision = "dfa909b99c79129e1100513e5cd36307665e5723"
|
revision = "8a410e7b638dca158bf9e766925842f6651ff828"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "golang.org/x/text"
|
name = "golang.org/x/text"
|
||||||
@ -118,7 +118,7 @@
|
|||||||
branch = "v1"
|
branch = "v1"
|
||||||
name = "gopkg.in/toast.v1"
|
name = "gopkg.in/toast.v1"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "b700e246b8b6d3e13554091e540e1019e26389f1"
|
revision = "0a84660828b24d25b35525c9a1f1f51267f8da91"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "gopkg.in/yaml.v2"
|
name = "gopkg.in/yaml.v2"
|
||||||
@ -130,7 +130,13 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "maunium.net/go/gomatrix"
|
name = "maunium.net/go/gomatrix"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "b491397f18b90e34ef54b8b3598666564b90b01a"
|
revision = "d651abc3ecb4bbd85a6b17b710632e73ddbbc6aa"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "maunium.net/go/maulogger"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "64f0aa33b6c51313e15575257db71dec44fe7988"
|
||||||
|
version = "v1.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -33,14 +33,14 @@ type MatrixContainer interface {
|
|||||||
Logout()
|
Logout()
|
||||||
|
|
||||||
SendPreferencesToMatrix()
|
SendPreferencesToMatrix()
|
||||||
SendMessage(roomID, msgtype, message string) (string, error)
|
SendMessage(roomID string, msgtype gomatrix.MessageType, message string) (string, error)
|
||||||
SendMarkdownMessage(roomID, msgtype, message string) (string, error)
|
SendMarkdownMessage(roomID string, msgtype gomatrix.MessageType, message string) (string, error)
|
||||||
SendTyping(roomID string, typing bool)
|
SendTyping(roomID string, typing bool)
|
||||||
MarkRead(roomID, eventID string)
|
MarkRead(roomID, eventID string)
|
||||||
JoinRoom(roomID, server string) (*rooms.Room, error)
|
JoinRoom(roomID, server string) (*rooms.Room, error)
|
||||||
LeaveRoom(roomID string) error
|
LeaveRoom(roomID string) error
|
||||||
|
|
||||||
GetHistory(roomID, prevBatch string, limit int) ([]gomatrix.Event, string, error)
|
GetHistory(roomID, prevBatch string, limit int) ([]*gomatrix.Event, string, error)
|
||||||
GetRoom(roomID string) *rooms.Room
|
GetRoom(roomID string) *rooms.Room
|
||||||
|
|
||||||
Download(mxcURL string) ([]byte, string, string, error)
|
Download(mxcURL string) ([]byte, string, string, error)
|
||||||
|
@ -73,8 +73,8 @@ type RoomView interface {
|
|||||||
SetTyping(users []string)
|
SetTyping(users []string)
|
||||||
UpdateUserList()
|
UpdateUserList()
|
||||||
|
|
||||||
NewMessage(id, sender, msgtype, text string, timestamp time.Time) Message
|
NewMessage(id, sender string, msgtype gomatrix.MessageType, text string, timestamp time.Time) Message
|
||||||
NewTempMessage(msgtype, text string) Message
|
NewTempMessage(msgtype gomatrix.MessageType, text string) Message
|
||||||
AddMessage(message Message, direction MessageDirection)
|
AddMessage(message Message, direction MessageDirection)
|
||||||
AddServiceMessage(message string)
|
AddServiceMessage(message string)
|
||||||
}
|
}
|
||||||
@ -111,8 +111,8 @@ type Message interface {
|
|||||||
SetID(id string)
|
SetID(id string)
|
||||||
ID() string
|
ID() string
|
||||||
|
|
||||||
SetType(msgtype string)
|
SetType(msgtype gomatrix.MessageType)
|
||||||
Type() string
|
Type() gomatrix.MessageType
|
||||||
|
|
||||||
NotificationContent() string
|
NotificationContent() string
|
||||||
|
|
||||||
|
@ -175,6 +175,8 @@ func (c *Container) PushRules() *pushrules.PushRuleset {
|
|||||||
return c.config.PushRules
|
return c.config.PushRules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AccountDataGomuksPreferences = gomatrix.NewEventType("net.maunium.gomuks.preferences")
|
||||||
|
|
||||||
// OnLogin initializes the syncer and updates the room list.
|
// OnLogin initializes the syncer and updates the room list.
|
||||||
func (c *Container) OnLogin() {
|
func (c *Container) OnLogin() {
|
||||||
c.ui.OnLogin()
|
c.ui.OnLogin()
|
||||||
@ -183,14 +185,14 @@ func (c *Container) OnLogin() {
|
|||||||
|
|
||||||
debug.Print("Initializing syncer")
|
debug.Print("Initializing syncer")
|
||||||
c.syncer = NewGomuksSyncer(c.config)
|
c.syncer = NewGomuksSyncer(c.config)
|
||||||
c.syncer.OnEventType("m.room.message", c.HandleMessage)
|
c.syncer.OnEventType(gomatrix.EventMessage, c.HandleMessage)
|
||||||
c.syncer.OnEventType("m.room.member", c.HandleMembership)
|
c.syncer.OnEventType(gomatrix.StateMember, c.HandleMembership)
|
||||||
c.syncer.OnEventType("m.receipt", c.HandleReadReceipt)
|
c.syncer.OnEventType(gomatrix.EphemeralEventReceipt, c.HandleReadReceipt)
|
||||||
c.syncer.OnEventType("m.typing", c.HandleTyping)
|
c.syncer.OnEventType(gomatrix.EphemeralEventTyping, c.HandleTyping)
|
||||||
c.syncer.OnEventType("m.direct", c.HandleDirectChatInfo)
|
c.syncer.OnEventType(gomatrix.AccountDataDirectChats, c.HandleDirectChatInfo)
|
||||||
c.syncer.OnEventType("m.push_rules", c.HandlePushRules)
|
c.syncer.OnEventType(gomatrix.AccountDataPushRules, c.HandlePushRules)
|
||||||
c.syncer.OnEventType("m.tag", c.HandleTag)
|
c.syncer.OnEventType(gomatrix.AccountDataRoomTags, c.HandleTag)
|
||||||
c.syncer.OnEventType("net.maunium.gomuks.preferences", c.HandlePreferences)
|
c.syncer.OnEventType(AccountDataGomuksPreferences, c.HandlePreferences)
|
||||||
c.syncer.InitDoneCallback = func() {
|
c.syncer.InitDoneCallback = func() {
|
||||||
c.config.AuthCache.InitialSyncDone = true
|
c.config.AuthCache.InitialSyncDone = true
|
||||||
c.config.SaveAuthCache()
|
c.config.SaveAuthCache()
|
||||||
@ -301,10 +303,10 @@ func (c *Container) HandleMembership(source EventSource, evt *gomatrix.Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) {
|
func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) {
|
||||||
membership, _ := evt.Content["membership"].(string)
|
membership := evt.Content.Membership
|
||||||
prevMembership := "leave"
|
prevMembership := gomatrix.MembershipLeave
|
||||||
if evt.Unsigned.PrevContent != nil {
|
if evt.Unsigned.PrevContent != nil {
|
||||||
prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string)
|
prevMembership = evt.Unsigned.PrevContent.Membership
|
||||||
}
|
}
|
||||||
debug.Printf("Processing own membership change: %s->%s in %s", prevMembership, membership, evt.RoomID)
|
debug.Printf("Processing own membership change: %s->%s in %s", prevMembership, membership, evt.RoomID)
|
||||||
if membership == prevMembership {
|
if membership == prevMembership {
|
||||||
@ -326,7 +328,7 @@ func (c *Container) processOwnMembershipChange(evt *gomatrix.Event) {
|
|||||||
|
|
||||||
func (c *Container) parseReadReceipt(evt *gomatrix.Event) (largestTimestampEvent string) {
|
func (c *Container) parseReadReceipt(evt *gomatrix.Event) (largestTimestampEvent string) {
|
||||||
var largestTimestamp int64
|
var largestTimestamp int64
|
||||||
for eventID, rawContent := range evt.Content {
|
for eventID, rawContent := range evt.Content.Raw {
|
||||||
content, ok := rawContent.(map[string]interface{})
|
content, ok := rawContent.(map[string]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
@ -368,7 +370,7 @@ func (c *Container) HandleReadReceipt(source EventSource, evt *gomatrix.Event) {
|
|||||||
|
|
||||||
func (c *Container) parseDirectChatInfo(evt *gomatrix.Event) map[*rooms.Room]bool {
|
func (c *Container) parseDirectChatInfo(evt *gomatrix.Event) map[*rooms.Room]bool {
|
||||||
directChats := make(map[*rooms.Room]bool)
|
directChats := make(map[*rooms.Room]bool)
|
||||||
for _, rawRoomIDList := range evt.Content {
|
for _, rawRoomIDList := range evt.Content.Raw {
|
||||||
roomIDList, ok := rawRoomIDList.([]interface{})
|
roomIDList, ok := rawRoomIDList.([]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
@ -416,15 +418,12 @@ func (c *Container) HandlePushRules(source EventSource, evt *gomatrix.Event) {
|
|||||||
func (c *Container) HandleTag(source EventSource, evt *gomatrix.Event) {
|
func (c *Container) HandleTag(source EventSource, evt *gomatrix.Event) {
|
||||||
room := c.config.GetRoom(evt.RoomID)
|
room := c.config.GetRoom(evt.RoomID)
|
||||||
|
|
||||||
tags, _ := evt.Content["tags"].(map[string]interface{})
|
newTags := make([]rooms.RoomTag, len(evt.Content.RoomTags))
|
||||||
newTags := make([]rooms.RoomTag, len(tags))
|
|
||||||
index := 0
|
index := 0
|
||||||
for tag, infoifc := range tags {
|
for tag, info := range evt.Content.RoomTags {
|
||||||
info, _ := infoifc.(map[string]interface{})
|
|
||||||
order := "0.5"
|
order := "0.5"
|
||||||
rawOrder, ok := info["order"]
|
if len(info.Order) > 0 {
|
||||||
if ok {
|
order = info.Order
|
||||||
order = fmt.Sprintf("%v", rawOrder)
|
|
||||||
}
|
}
|
||||||
newTags[index] = rooms.RoomTag{
|
newTags[index] = rooms.RoomTag{
|
||||||
Tag: tag,
|
Tag: tag,
|
||||||
@ -440,13 +439,7 @@ func (c *Container) HandleTag(source EventSource, evt *gomatrix.Event) {
|
|||||||
|
|
||||||
// HandleTyping is the event handler for the m.typing event.
|
// HandleTyping is the event handler for the m.typing event.
|
||||||
func (c *Container) HandleTyping(source EventSource, evt *gomatrix.Event) {
|
func (c *Container) HandleTyping(source EventSource, evt *gomatrix.Event) {
|
||||||
users := evt.Content["user_ids"].([]interface{})
|
c.ui.MainView().SetTyping(evt.RoomID, evt.Content.TypingUserIDs)
|
||||||
|
|
||||||
strUsers := make([]string, len(users))
|
|
||||||
for i, user := range users {
|
|
||||||
strUsers[i] = user.(string)
|
|
||||||
}
|
|
||||||
c.ui.MainView().SetTyping(evt.RoomID, strUsers)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) MarkRead(roomID, eventID string) {
|
func (c *Container) MarkRead(roomID, eventID string) {
|
||||||
@ -455,11 +448,11 @@ func (c *Container) MarkRead(roomID, eventID string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SendMessage sends a message with the given text to the given room.
|
// SendMessage sends a message with the given text to the given room.
|
||||||
func (c *Container) SendMessage(roomID, msgtype, text string) (string, error) {
|
func (c *Container) SendMessage(roomID string, msgtype gomatrix.MessageType, text string) (string, error) {
|
||||||
defer debug.Recover()
|
defer debug.Recover()
|
||||||
c.SendTyping(roomID, false)
|
c.SendTyping(roomID, false)
|
||||||
resp, err := c.client.SendMessageEvent(roomID, "m.room.message",
|
resp, err := c.client.SendMessageEvent(roomID, gomatrix.EventMessage,
|
||||||
gomatrix.TextMessage{MsgType: msgtype, Body: text})
|
gomatrix.Content{MsgType: msgtype, Body: text})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -498,7 +491,7 @@ var roomRegex = regexp.MustCompile("\\[.+?]\\(https://matrix.to/#/(#.+?:[^/]+?)\
|
|||||||
//
|
//
|
||||||
// If the given text contains markdown formatting symbols, it will be rendered into HTML before sending.
|
// If the given text contains markdown formatting symbols, it will be rendered into HTML before sending.
|
||||||
// Otherwise, it will be sent as plain text.
|
// Otherwise, it will be sent as plain text.
|
||||||
func (c *Container) SendMarkdownMessage(roomID, msgtype, text string) (string, error) {
|
func (c *Container) SendMarkdownMessage(roomID string, msgtype gomatrix.MessageType, text string) (string, error) {
|
||||||
defer debug.Recover()
|
defer debug.Recover()
|
||||||
|
|
||||||
html := c.renderMarkdown(text)
|
html := c.renderMarkdown(text)
|
||||||
@ -511,12 +504,12 @@ func (c *Container) SendMarkdownMessage(roomID, msgtype, text string) (string, e
|
|||||||
text = roomRegex.ReplaceAllString(text, "$1")
|
text = roomRegex.ReplaceAllString(text, "$1")
|
||||||
|
|
||||||
c.SendTyping(roomID, false)
|
c.SendTyping(roomID, false)
|
||||||
resp, err := c.client.SendMessageEvent(roomID, "m.room.message",
|
resp, err := c.client.SendMessageEvent(roomID, gomatrix.EventMessage,
|
||||||
map[string]interface{}{
|
gomatrix.Content{
|
||||||
"msgtype": msgtype,
|
MsgType: msgtype,
|
||||||
"body": text,
|
Body: text,
|
||||||
"format": "org.matrix.custom.html",
|
Format: gomatrix.FormatHTML,
|
||||||
"formatted_body": html,
|
FormattedBody: html,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -567,7 +560,7 @@ func (c *Container) LeaveRoom(roomID string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetHistory fetches room history.
|
// GetHistory fetches room history.
|
||||||
func (c *Container) GetHistory(roomID, prevBatch string, limit int) ([]gomatrix.Event, string, error) {
|
func (c *Container) GetHistory(roomID, prevBatch string, limit int) ([]*gomatrix.Event, string, error) {
|
||||||
resp, err := c.client.Messages(roomID, prevBatch, "", 'b', limit)
|
resp, err := c.client.Messages(roomID, prevBatch, "", 'b', limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
|
@ -23,14 +23,13 @@ import (
|
|||||||
|
|
||||||
"maunium.net/go/gomatrix"
|
"maunium.net/go/gomatrix"
|
||||||
"maunium.net/go/gomuks/lib/glob"
|
"maunium.net/go/gomuks/lib/glob"
|
||||||
"maunium.net/go/gomuks/matrix/rooms"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Room is an interface with the functions that are needed for processing room-specific push conditions
|
// Room is an interface with the functions that are needed for processing room-specific push conditions
|
||||||
type Room interface {
|
type Room interface {
|
||||||
GetMember(mxid string) *rooms.Member
|
GetMember(mxid string) *gomatrix.Member
|
||||||
GetMembers() map[string]*rooms.Member
|
GetMembers() map[string]*gomatrix.Member
|
||||||
GetSessionOwner() *rooms.Member
|
GetSessionOwner() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// PushCondKind is the type of a push condition.
|
// PushCondKind is the type of a push condition.
|
||||||
@ -89,7 +88,7 @@ func (cond *PushCondition) matchValue(room Room, event *gomatrix.Event) bool {
|
|||||||
|
|
||||||
switch key {
|
switch key {
|
||||||
case "type":
|
case "type":
|
||||||
return pattern.MatchString(event.Type)
|
return pattern.MatchString(event.Type.String())
|
||||||
case "sender":
|
case "sender":
|
||||||
return pattern.MatchString(event.Sender)
|
return pattern.MatchString(event.Sender)
|
||||||
case "room_id":
|
case "room_id":
|
||||||
@ -100,7 +99,7 @@ func (cond *PushCondition) matchValue(room Room, event *gomatrix.Event) bool {
|
|||||||
}
|
}
|
||||||
return pattern.MatchString(*event.StateKey)
|
return pattern.MatchString(*event.StateKey)
|
||||||
case "content":
|
case "content":
|
||||||
val, _ := event.Content[subkey].(string)
|
val, _ := event.Content.Raw[subkey].(string)
|
||||||
return pattern.MatchString(val)
|
return pattern.MatchString(val)
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
@ -108,12 +107,12 @@ func (cond *PushCondition) matchValue(room Room, event *gomatrix.Event) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cond *PushCondition) matchDisplayName(room Room, event *gomatrix.Event) bool {
|
func (cond *PushCondition) matchDisplayName(room Room, event *gomatrix.Event) bool {
|
||||||
member := room.GetSessionOwner()
|
ownerID := room.GetSessionOwner()
|
||||||
if member == nil || member.UserID == event.Sender {
|
if ownerID == event.Sender {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
text, _ := event.Content["body"].(string)
|
member := room.GetMember(ownerID)
|
||||||
return strings.Contains(text, member.DisplayName)
|
return strings.Contains(event.Content.Body, member.Displayname)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cond *PushCondition) matchMemberCount(room Room, event *gomatrix.Event) bool {
|
func (cond *PushCondition) matchMemberCount(room Room, event *gomatrix.Event) bool {
|
||||||
|
@ -21,19 +21,17 @@ func GetScopedPushRules(client *gomatrix.Client, scope string) (resp *PushRulese
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type contentWithRuleset struct {
|
||||||
|
Ruleset *PushRuleset `json:"global"`
|
||||||
|
}
|
||||||
|
|
||||||
// EventToPushRules converts a m.push_rules event to a PushRuleset by passing the data through JSON.
|
// EventToPushRules converts a m.push_rules event to a PushRuleset by passing the data through JSON.
|
||||||
func EventToPushRules(event *gomatrix.Event) (*PushRuleset, error) {
|
func EventToPushRules(event *gomatrix.Event) (*PushRuleset, error) {
|
||||||
content, _ := event.Content["global"]
|
content := &contentWithRuleset{}
|
||||||
raw, err := json.Marshal(content)
|
err := json.Unmarshal(event.Content.VeryRaw, content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ruleset := &PushRuleset{}
|
return content.Ruleset, nil
|
||||||
err = json.Unmarshal(raw, ruleset)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ruleset, nil
|
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,5 @@ func (rule *PushRule) matchPattern(room Room, event *gomatrix.Event) bool {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
text, _ := event.Content["body"].(string)
|
return pattern.MatchString(event.Content.Body)
|
||||||
return pattern.MatchString(text)
|
|
||||||
}
|
}
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
// gomuks - A terminal Matrix client written in Go.
|
|
||||||
// Copyright (C) 2018 Tulir Asokan
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package rooms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"maunium.net/go/gomatrix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Membership is an enum specifying the membership state of a room member.
|
|
||||||
type Membership string
|
|
||||||
|
|
||||||
// The allowed membership states as specified in spec section 10.5.5.
|
|
||||||
const (
|
|
||||||
MembershipJoin Membership = "join"
|
|
||||||
MembershipLeave Membership = "leave"
|
|
||||||
MembershipInvite Membership = "invite"
|
|
||||||
MembershipBan Membership = "ban"
|
|
||||||
MembershipKnock Membership = "knock"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Member represents a member in a room.
|
|
||||||
type Member struct {
|
|
||||||
// The MXID of the member.
|
|
||||||
UserID string `json:"-"`
|
|
||||||
// The membership status. Defaults to leave.
|
|
||||||
Membership Membership `json:"membership"`
|
|
||||||
// The display name of the user. Defaults to the user ID.
|
|
||||||
DisplayName string `json:"displayname"`
|
|
||||||
// The avatar URL of the user. Defaults to an empty string.
|
|
||||||
AvatarURL string `json:"avatar_url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// eventToRoomMember converts a m.room.member state event into a Member object.
|
|
||||||
func eventToRoomMember(userID string, event *gomatrix.Event) *Member {
|
|
||||||
membership, _ := event.Content["membership"].(string)
|
|
||||||
avatarURL, _ := event.Content["avatar_url"].(string)
|
|
||||||
|
|
||||||
displayName, _ := event.Content["displayname"].(string)
|
|
||||||
if len(displayName) == 0 {
|
|
||||||
displayName = userID
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Member{
|
|
||||||
UserID: userID,
|
|
||||||
Membership: Membership(membership),
|
|
||||||
DisplayName: displayName,
|
|
||||||
AvatarURL: avatarURL,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
// gomuks - A terminal Matrix client written in Go.
|
|
||||||
// Copyright (C) 2018 Tulir Asokan
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package rooms_test
|
|
@ -82,10 +82,10 @@ type Room struct {
|
|||||||
LastReceivedMessage time.Time
|
LastReceivedMessage time.Time
|
||||||
|
|
||||||
// MXID -> Member cache calculated from membership events.
|
// MXID -> Member cache calculated from membership events.
|
||||||
memberCache map[string]*Member
|
memberCache map[string]*gomatrix.Member
|
||||||
// The first non-SessionUserID member in the room. Calculated at
|
// The first non-SessionUserID member in the room. Calculated at
|
||||||
// the same time as memberCache.
|
// the same time as memberCache.
|
||||||
firstMemberCache *Member
|
firstMemberCache *gomatrix.Member
|
||||||
// The name of the room. Calculated from the state event name,
|
// The name of the room. Calculated from the state event name,
|
||||||
// canonical_alias or alias or the member cache.
|
// canonical_alias or alias or the member cache.
|
||||||
nameCache string
|
nameCache string
|
||||||
@ -222,25 +222,25 @@ func (room *Room) UpdateState(event *gomatrix.Event) {
|
|||||||
room.State[event.Type] = make(map[string]*gomatrix.Event)
|
room.State[event.Type] = make(map[string]*gomatrix.Event)
|
||||||
}
|
}
|
||||||
switch event.Type {
|
switch event.Type {
|
||||||
case "m.room.name":
|
case gomatrix.StateRoomName:
|
||||||
room.nameCache = ""
|
room.nameCache = ""
|
||||||
case "m.room.canonical_alias":
|
case gomatrix.StateCanonicalAlias:
|
||||||
if room.nameCacheSource >= CanonicalAliasRoomName {
|
if room.nameCacheSource >= CanonicalAliasRoomName {
|
||||||
room.nameCache = ""
|
room.nameCache = ""
|
||||||
}
|
}
|
||||||
room.canonicalAliasCache = ""
|
room.canonicalAliasCache = ""
|
||||||
case "m.room.aliases":
|
case gomatrix.StateAliases:
|
||||||
if room.nameCacheSource >= AliasRoomName {
|
if room.nameCacheSource >= AliasRoomName {
|
||||||
room.nameCache = ""
|
room.nameCache = ""
|
||||||
}
|
}
|
||||||
room.aliasesCache = nil
|
room.aliasesCache = nil
|
||||||
case "m.room.member":
|
case gomatrix.StateMember:
|
||||||
room.memberCache = nil
|
room.memberCache = nil
|
||||||
room.firstMemberCache = nil
|
room.firstMemberCache = nil
|
||||||
if room.nameCacheSource >= MemberRoomName {
|
if room.nameCacheSource >= MemberRoomName {
|
||||||
room.nameCache = ""
|
room.nameCache = ""
|
||||||
}
|
}
|
||||||
case "m.room.topic":
|
case gomatrix.StateTopic:
|
||||||
room.topicCache = ""
|
room.topicCache = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +248,7 @@ func (room *Room) UpdateState(event *gomatrix.Event) {
|
|||||||
if event.StateKey != nil {
|
if event.StateKey != nil {
|
||||||
stateKey = *event.StateKey
|
stateKey = *event.StateKey
|
||||||
}
|
}
|
||||||
if event.Type != "m.room.member" {
|
if event.Type != gomatrix.StateMember {
|
||||||
debug.Printf("Updating state %s#%s for %s", event.Type, stateKey, room.ID)
|
debug.Printf("Updating state %s#%s for %s", event.Type, stateKey, room.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,14 +260,14 @@ func (room *Room) UpdateState(event *gomatrix.Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetStateEvent returns the state event for the given type/state_key combo, or nil.
|
// GetStateEvent returns the state event for the given type/state_key combo, or nil.
|
||||||
func (room *Room) GetStateEvent(eventType string, stateKey string) *gomatrix.Event {
|
func (room *Room) GetStateEvent(eventType gomatrix.EventType, stateKey string) *gomatrix.Event {
|
||||||
stateEventMap, _ := room.State[eventType]
|
stateEventMap, _ := room.State[eventType]
|
||||||
event, _ := stateEventMap[stateKey]
|
event, _ := stateEventMap[stateKey]
|
||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStateEvents returns the state events for the given type.
|
// GetStateEvents returns the state events for the given type.
|
||||||
func (room *Room) GetStateEvents(eventType string) map[string]*gomatrix.Event {
|
func (room *Room) GetStateEvents(eventType gomatrix.EventType) map[string]*gomatrix.Event {
|
||||||
stateEventMap, _ := room.State[eventType]
|
stateEventMap, _ := room.State[eventType]
|
||||||
return stateEventMap
|
return stateEventMap
|
||||||
}
|
}
|
||||||
@ -275,9 +275,9 @@ func (room *Room) GetStateEvents(eventType string) map[string]*gomatrix.Event {
|
|||||||
// GetTopic returns the topic of the room.
|
// GetTopic returns the topic of the room.
|
||||||
func (room *Room) GetTopic() string {
|
func (room *Room) GetTopic() string {
|
||||||
if len(room.topicCache) == 0 {
|
if len(room.topicCache) == 0 {
|
||||||
topicEvt := room.GetStateEvent("m.room.topic", "")
|
topicEvt := room.GetStateEvent(gomatrix.StateTopic, "")
|
||||||
if topicEvt != nil {
|
if topicEvt != nil {
|
||||||
room.topicCache, _ = topicEvt.Content["topic"].(string)
|
room.topicCache = topicEvt.Content.Topic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return room.topicCache
|
return room.topicCache
|
||||||
@ -285,9 +285,9 @@ func (room *Room) GetTopic() string {
|
|||||||
|
|
||||||
func (room *Room) GetCanonicalAlias() string {
|
func (room *Room) GetCanonicalAlias() string {
|
||||||
if len(room.canonicalAliasCache) == 0 {
|
if len(room.canonicalAliasCache) == 0 {
|
||||||
canonicalAliasEvt := room.GetStateEvent("m.room.canonical_alias", "")
|
canonicalAliasEvt := room.GetStateEvent(gomatrix.StateCanonicalAlias, "")
|
||||||
if canonicalAliasEvt != nil {
|
if canonicalAliasEvt != nil {
|
||||||
room.canonicalAliasCache, _ = canonicalAliasEvt.Content["alias"].(string)
|
room.canonicalAliasCache = canonicalAliasEvt.Content.Alias
|
||||||
} else {
|
} else {
|
||||||
room.canonicalAliasCache = "-"
|
room.canonicalAliasCache = "-"
|
||||||
}
|
}
|
||||||
@ -301,17 +301,10 @@ func (room *Room) GetCanonicalAlias() string {
|
|||||||
// GetAliases returns the list of aliases that point to this room.
|
// GetAliases returns the list of aliases that point to this room.
|
||||||
func (room *Room) GetAliases() []string {
|
func (room *Room) GetAliases() []string {
|
||||||
if room.aliasesCache == nil {
|
if room.aliasesCache == nil {
|
||||||
aliasEvents := room.GetStateEvents("m.room.aliases")
|
aliasEvents := room.GetStateEvents(gomatrix.StateAliases)
|
||||||
room.aliasesCache = []string{}
|
room.aliasesCache = []string{}
|
||||||
for _, event := range aliasEvents {
|
for _, event := range aliasEvents {
|
||||||
aliases, _ := event.Content["aliases"].([]interface{})
|
room.aliasesCache = append(room.aliasesCache, event.Content.Aliases...)
|
||||||
|
|
||||||
newAliases := make([]string, len(room.aliasesCache)+len(aliases))
|
|
||||||
copy(newAliases, room.aliasesCache)
|
|
||||||
for index, alias := range aliases {
|
|
||||||
newAliases[len(room.aliasesCache)+index], _ = alias.(string)
|
|
||||||
}
|
|
||||||
room.aliasesCache = newAliases
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return room.aliasesCache
|
return room.aliasesCache
|
||||||
@ -319,9 +312,9 @@ func (room *Room) GetAliases() []string {
|
|||||||
|
|
||||||
// updateNameFromNameEvent updates the room display name to be the name set in the name event.
|
// updateNameFromNameEvent updates the room display name to be the name set in the name event.
|
||||||
func (room *Room) updateNameFromNameEvent() {
|
func (room *Room) updateNameFromNameEvent() {
|
||||||
nameEvt := room.GetStateEvent("m.room.name", "")
|
nameEvt := room.GetStateEvent(gomatrix.StateRoomName, "")
|
||||||
if nameEvt != nil {
|
if nameEvt != nil {
|
||||||
room.nameCache, _ = nameEvt.Content["name"].(string)
|
room.nameCache = nameEvt.Content.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,9 +346,9 @@ func (room *Room) updateNameFromMembers() {
|
|||||||
} else if room.firstMemberCache == nil {
|
} else if room.firstMemberCache == nil {
|
||||||
room.nameCache = "Room"
|
room.nameCache = "Room"
|
||||||
} else if len(members) == 2 {
|
} else if len(members) == 2 {
|
||||||
room.nameCache = room.firstMemberCache.DisplayName
|
room.nameCache = room.firstMemberCache.Displayname
|
||||||
} else {
|
} else {
|
||||||
firstMember := room.firstMemberCache.DisplayName
|
firstMember := room.firstMemberCache.Displayname
|
||||||
room.nameCache = fmt.Sprintf("%s and %d others", firstMember, len(members)-2)
|
room.nameCache = fmt.Sprintf("%s and %d others", firstMember, len(members)-2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -391,18 +384,18 @@ func (room *Room) GetTitle() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createMemberCache caches all member events into a easily processable MXID -> *Member map.
|
// createMemberCache caches all member events into a easily processable MXID -> *Member map.
|
||||||
func (room *Room) createMemberCache() map[string]*Member {
|
func (room *Room) createMemberCache() map[string]*gomatrix.Member {
|
||||||
cache := make(map[string]*Member)
|
cache := make(map[string]*gomatrix.Member)
|
||||||
events := room.GetStateEvents("m.room.member")
|
events := room.GetStateEvents(gomatrix.StateMember)
|
||||||
room.firstMemberCache = nil
|
room.firstMemberCache = nil
|
||||||
if events != nil {
|
if events != nil {
|
||||||
for userID, event := range events {
|
for userID, event := range events {
|
||||||
member := eventToRoomMember(userID, event)
|
member := &event.Content.Member
|
||||||
if room.firstMemberCache == nil && userID != room.SessionUserID {
|
if room.firstMemberCache == nil && userID != room.SessionUserID {
|
||||||
room.firstMemberCache = member
|
room.firstMemberCache = member
|
||||||
}
|
}
|
||||||
if member.Membership != "leave" {
|
if member.Membership != "leave" {
|
||||||
cache[member.UserID] = member
|
cache[userID] = member
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -414,7 +407,7 @@ func (room *Room) createMemberCache() map[string]*Member {
|
|||||||
//
|
//
|
||||||
// The members are returned from the cache.
|
// The members are returned from the cache.
|
||||||
// If the cache is empty, it is updated first.
|
// If the cache is empty, it is updated first.
|
||||||
func (room *Room) GetMembers() map[string]*Member {
|
func (room *Room) GetMembers() map[string]*gomatrix.Member {
|
||||||
if len(room.memberCache) == 0 || room.firstMemberCache == nil {
|
if len(room.memberCache) == 0 || room.firstMemberCache == nil {
|
||||||
room.createMemberCache()
|
room.createMemberCache()
|
||||||
}
|
}
|
||||||
@ -423,7 +416,7 @@ func (room *Room) GetMembers() map[string]*Member {
|
|||||||
|
|
||||||
// GetMember returns the member with the given MXID.
|
// GetMember returns the member with the given MXID.
|
||||||
// If the member doesn't exist, nil is returned.
|
// If the member doesn't exist, nil is returned.
|
||||||
func (room *Room) GetMember(userID string) *Member {
|
func (room *Room) GetMember(userID string) *gomatrix.Member {
|
||||||
if len(room.memberCache) == 0 {
|
if len(room.memberCache) == 0 {
|
||||||
room.createMemberCache()
|
room.createMemberCache()
|
||||||
}
|
}
|
||||||
@ -432,8 +425,8 @@ func (room *Room) GetMember(userID string) *Member {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSessionOwner returns the Member instance of the user whose session this room was created for.
|
// GetSessionOwner returns the Member instance of the user whose session this room was created for.
|
||||||
func (room *Room) GetSessionOwner() *Member {
|
func (room *Room) GetSessionOwner() string {
|
||||||
return room.GetMember(room.SessionUserID)
|
return room.SessionUserID
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRoom creates a new Room with the given ID
|
// NewRoom creates a new Room with the given ID
|
||||||
|
@ -51,7 +51,7 @@ type EventHandler func(source EventSource, event *gomatrix.Event)
|
|||||||
// pattern to notify callers about incoming events. See GomuksSyncer.OnEventType for more information.
|
// pattern to notify callers about incoming events. See GomuksSyncer.OnEventType for more information.
|
||||||
type GomuksSyncer struct {
|
type GomuksSyncer struct {
|
||||||
Session SyncerSession
|
Session SyncerSession
|
||||||
listeners map[string][]EventHandler // event type to listeners array
|
listeners map[gomatrix.EventType][]EventHandler // event type to listeners array
|
||||||
FirstSyncDone bool
|
FirstSyncDone bool
|
||||||
InitDoneCallback func()
|
InitDoneCallback func()
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ type GomuksSyncer struct {
|
|||||||
func NewGomuksSyncer(session SyncerSession) *GomuksSyncer {
|
func NewGomuksSyncer(session SyncerSession) *GomuksSyncer {
|
||||||
return &GomuksSyncer{
|
return &GomuksSyncer{
|
||||||
Session: session,
|
Session: session,
|
||||||
listeners: make(map[string][]EventHandler),
|
listeners: make(map[gomatrix.EventType][]EventHandler),
|
||||||
FirstSyncDone: false,
|
FirstSyncDone: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,20 +114,11 @@ func (s *GomuksSyncer) processSyncEvents(room *rooms.Room, events []*gomatrix.Ev
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isState(event *gomatrix.Event) bool {
|
|
||||||
switch event.Type {
|
|
||||||
case "m.room.member", "m.room.name", "m.room.topic", "m.room.aliases", "m.room.canonical_alias":
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GomuksSyncer) processSyncEvent(room *rooms.Room, event *gomatrix.Event, source EventSource) {
|
func (s *GomuksSyncer) processSyncEvent(room *rooms.Room, event *gomatrix.Event, source EventSource) {
|
||||||
if room != nil {
|
if room != nil {
|
||||||
event.RoomID = room.ID
|
event.RoomID = room.ID
|
||||||
}
|
}
|
||||||
if isState(event) {
|
if event.Type.Class == gomatrix.StateEventType {
|
||||||
room.UpdateState(event)
|
room.UpdateState(event)
|
||||||
}
|
}
|
||||||
s.notifyListeners(source, event)
|
s.notifyListeners(source, event)
|
||||||
@ -135,7 +126,7 @@ func (s *GomuksSyncer) processSyncEvent(room *rooms.Room, event *gomatrix.Event,
|
|||||||
|
|
||||||
// OnEventType allows callers to be notified when there are new events for the given event type.
|
// OnEventType allows callers to be notified when there are new events for the given event type.
|
||||||
// There are no duplicate checks.
|
// There are no duplicate checks.
|
||||||
func (s *GomuksSyncer) OnEventType(eventType string, callback EventHandler) {
|
func (s *GomuksSyncer) OnEventType(eventType gomatrix.EventType, callback EventHandler) {
|
||||||
_, exists := s.listeners[eventType]
|
_, exists := s.listeners[eventType]
|
||||||
if !exists {
|
if !exists {
|
||||||
s.listeners[eventType] = []EventHandler{}
|
s.listeners[eventType] = []EventHandler{}
|
||||||
|
@ -19,6 +19,7 @@ package ui
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maunium.net/go/gomatrix"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
@ -132,7 +133,7 @@ func cmdSendEvent(cmd *Command) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
roomID := cmd.Args[0]
|
roomID := cmd.Args[0]
|
||||||
eventType := cmd.Args[1]
|
eventType := gomatrix.NewEventType(cmd.Args[1])
|
||||||
rawContent := strings.Join(cmd.Args[2:], "")
|
rawContent := strings.Join(cmd.Args[2:], "")
|
||||||
debug.Print(roomID, eventType, rawContent)
|
debug.Print(roomID, eventType, rawContent)
|
||||||
|
|
||||||
@ -161,7 +162,7 @@ func cmdSetState(cmd *Command) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
roomID := cmd.Args[0]
|
roomID := cmd.Args[0]
|
||||||
eventType := cmd.Args[1]
|
eventType := gomatrix.NewEventType(cmd.Args[1])
|
||||||
stateKey := cmd.Args[2]
|
stateKey := cmd.Args[2]
|
||||||
if stateKey == "-" {
|
if stateKey == "-" {
|
||||||
stateKey = ""
|
stateKey = ""
|
||||||
|
@ -18,6 +18,7 @@ package messages
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
"maunium.net/go/gomatrix"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"maunium.net/go/gomuks/config"
|
"maunium.net/go/gomuks/config"
|
||||||
@ -33,7 +34,7 @@ func init() {
|
|||||||
|
|
||||||
type BaseMessage struct {
|
type BaseMessage struct {
|
||||||
MsgID string
|
MsgID string
|
||||||
MsgType string
|
MsgType gomatrix.MessageType
|
||||||
MsgSenderID string
|
MsgSenderID string
|
||||||
MsgSender string
|
MsgSender string
|
||||||
MsgSenderColor tcell.Color
|
MsgSenderColor tcell.Color
|
||||||
@ -47,7 +48,7 @@ type BaseMessage struct {
|
|||||||
prevPrefs config.UserPreferences
|
prevPrefs config.UserPreferences
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBaseMessage(id, sender, displayname, msgtype string, timestamp time.Time) BaseMessage {
|
func newBaseMessage(id, sender, displayname string, msgtype gomatrix.MessageType, timestamp time.Time) BaseMessage {
|
||||||
return BaseMessage{
|
return BaseMessage{
|
||||||
MsgSenderID: sender,
|
MsgSenderID: sender,
|
||||||
MsgSender: displayname,
|
MsgSender: displayname,
|
||||||
@ -194,11 +195,11 @@ func (msg *BaseMessage) SetID(id string) {
|
|||||||
msg.MsgID = id
|
msg.MsgID = id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *BaseMessage) Type() string {
|
func (msg *BaseMessage) Type() gomatrix.MessageType {
|
||||||
return msg.MsgType
|
return msg.MsgType
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *BaseMessage) SetType(msgtype string) {
|
func (msg *BaseMessage) SetType(msgtype gomatrix.MessageType) {
|
||||||
msg.MsgType = msgtype
|
msg.MsgType = msgtype
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ package messages
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
"maunium.net/go/gomatrix"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"maunium.net/go/gomuks/config"
|
"maunium.net/go/gomuks/config"
|
||||||
@ -34,7 +35,7 @@ type ExpandedTextMessage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewExpandedTextMessage creates a new ExpandedTextMessage object with the provided values and the default state.
|
// NewExpandedTextMessage creates a new ExpandedTextMessage object with the provided values and the default state.
|
||||||
func NewExpandedTextMessage(id, sender, displayname, msgtype string, text tstring.TString, timestamp time.Time) UIMessage {
|
func NewExpandedTextMessage(id, sender, displayname string, msgtype gomatrix.MessageType, text tstring.TString, timestamp time.Time) UIMessage {
|
||||||
return &ExpandedTextMessage{
|
return &ExpandedTextMessage{
|
||||||
BaseMessage: newBaseMessage(id, sender, displayname, msgtype, timestamp),
|
BaseMessage: newBaseMessage(id, sender, displayname, msgtype, timestamp),
|
||||||
MsgText: text,
|
MsgText: text,
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maunium.net/go/gomatrix"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"image/color"
|
"image/color"
|
||||||
@ -47,7 +48,7 @@ type ImageMessage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewImageMessage creates a new ImageMessage object with the provided values and the default state.
|
// NewImageMessage creates a new ImageMessage object with the provided values and the default state.
|
||||||
func NewImageMessage(matrix ifc.MatrixContainer, id, sender, displayname, msgtype, body, homeserver, fileID string, data []byte, timestamp time.Time) UIMessage {
|
func NewImageMessage(matrix ifc.MatrixContainer, id, sender, displayname string, msgtype gomatrix.MessageType, body, homeserver, fileID string, data []byte, timestamp time.Time) UIMessage {
|
||||||
return &ImageMessage{
|
return &ImageMessage{
|
||||||
newBaseMessage(id, sender, displayname, msgtype, timestamp),
|
newBaseMessage(id, sender, displayname, msgtype, timestamp),
|
||||||
body,
|
body,
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/lucasb-eyer/go-colorful"
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
"maunium.net/go/gomatrix"
|
"maunium.net/go/gomatrix"
|
||||||
"maunium.net/go/gomuks/matrix/rooms"
|
"maunium.net/go/gomuks/matrix/rooms"
|
||||||
@ -29,7 +30,6 @@ import (
|
|||||||
"maunium.net/go/gomuks/ui/widget"
|
"maunium.net/go/gomuks/ui/widget"
|
||||||
"maunium.net/go/tcell"
|
"maunium.net/go/tcell"
|
||||||
"strconv"
|
"strconv"
|
||||||
"github.com/lucasb-eyer/go-colorful"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var matrixToURL = regexp.MustCompile("^(?:https?://)?(?:www\\.)?matrix\\.to/#/([#@!].*)")
|
var matrixToURL = regexp.MustCompile("^(?:https?://)?(?:www\\.)?matrix\\.to/#/([#@!].*)")
|
||||||
@ -173,7 +173,7 @@ func (parser *htmlParser) linkToTString(node *html.Node, stripLinebreak bool) ts
|
|||||||
pillTarget := match[1]
|
pillTarget := match[1]
|
||||||
if pillTarget[0] == '@' {
|
if pillTarget[0] == '@' {
|
||||||
if member := parser.room.GetMember(pillTarget); member != nil {
|
if member := parser.room.GetMember(pillTarget); member != nil {
|
||||||
return tstring.NewColorTString(member.DisplayName, widget.GetHashColor(member.UserID))
|
return tstring.NewColorTString(member.Displayname, widget.GetHashColor(pillTarget))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tstring.NewTString(pillTarget)
|
return tstring.NewTString(pillTarget)
|
||||||
@ -271,14 +271,13 @@ func (parser *htmlParser) Parse(htmlData string) tstring.TString {
|
|||||||
|
|
||||||
// ParseHTMLMessage parses a HTML-formatted Matrix event into a UIMessage.
|
// ParseHTMLMessage parses a HTML-formatted Matrix event into a UIMessage.
|
||||||
func ParseHTMLMessage(room *rooms.Room, evt *gomatrix.Event, senderDisplayname string) tstring.TString {
|
func ParseHTMLMessage(room *rooms.Room, evt *gomatrix.Event, senderDisplayname string) tstring.TString {
|
||||||
htmlData, _ := evt.Content["formatted_body"].(string)
|
htmlData := evt.Content.FormattedBody
|
||||||
htmlData = strings.Replace(htmlData, "\t", " ", -1)
|
htmlData = strings.Replace(htmlData, "\t", " ", -1)
|
||||||
|
|
||||||
parser := htmlParser{room}
|
parser := htmlParser{room}
|
||||||
str := parser.Parse(htmlData)
|
str := parser.Parse(htmlData)
|
||||||
|
|
||||||
msgtype, _ := evt.Content["msgtype"].(string)
|
if evt.Content.MsgType == gomatrix.MsgEmote {
|
||||||
if msgtype == "m.emote" {
|
|
||||||
str = tstring.Join([]tstring.TString{
|
str = tstring.Join([]tstring.TString{
|
||||||
tstring.NewTString("* "),
|
tstring.NewTString("* "),
|
||||||
tstring.NewColorTString(senderDisplayname, widget.GetHashColor(evt.Sender)),
|
tstring.NewColorTString(senderDisplayname, widget.GetHashColor(evt.Sender)),
|
||||||
|
@ -33,9 +33,9 @@ import (
|
|||||||
|
|
||||||
func ParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Event) messages.UIMessage {
|
func ParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Event) messages.UIMessage {
|
||||||
switch evt.Type {
|
switch evt.Type {
|
||||||
case "m.room.message":
|
case gomatrix.EventMessage:
|
||||||
return ParseMessage(matrix, room, evt)
|
return ParseMessage(matrix, room, evt)
|
||||||
case "m.room.member":
|
case gomatrix.StateMember:
|
||||||
return ParseMembershipEvent(room, evt)
|
return ParseMembershipEvent(room, evt)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -53,32 +53,28 @@ func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Ev
|
|||||||
displayname := evt.Sender
|
displayname := evt.Sender
|
||||||
member := room.GetMember(evt.Sender)
|
member := room.GetMember(evt.Sender)
|
||||||
if member != nil {
|
if member != nil {
|
||||||
displayname = member.DisplayName
|
displayname = member.Displayname
|
||||||
}
|
}
|
||||||
msgtype, _ := evt.Content["msgtype"].(string)
|
|
||||||
text, _ := evt.Content["body"].(string)
|
|
||||||
ts := unixToTime(evt.Timestamp)
|
ts := unixToTime(evt.Timestamp)
|
||||||
switch msgtype {
|
switch evt.Content.MsgType {
|
||||||
case "m.text", "m.notice", "m.emote":
|
case "m.text", "m.notice", "m.emote":
|
||||||
format, hasFormat := evt.Content["format"].(string)
|
if evt.Content.Format == gomatrix.FormatHTML {
|
||||||
if hasFormat && format == "org.matrix.custom.html" {
|
|
||||||
text := ParseHTMLMessage(room, evt, displayname)
|
text := ParseHTMLMessage(room, evt, displayname)
|
||||||
return messages.NewExpandedTextMessage(evt.ID, evt.Sender, displayname, msgtype, text, ts)
|
return messages.NewExpandedTextMessage(evt.ID, evt.Sender, displayname, evt.Content.MsgType, text, ts)
|
||||||
}
|
}
|
||||||
text = strings.Replace(text, "\t", " ", -1)
|
evt.Content.Body = strings.Replace(evt.Content.Body, "\t", " ", -1)
|
||||||
return messages.NewTextMessage(evt.ID, evt.Sender, displayname, msgtype, text, ts)
|
return messages.NewTextMessage(evt.ID, evt.Sender, displayname, evt.Content.MsgType, evt.Content.Body, ts)
|
||||||
case "m.image":
|
case "m.image":
|
||||||
url, _ := evt.Content["url"].(string)
|
data, hs, id, err := matrix.Download(evt.Content.URL)
|
||||||
data, hs, id, err := matrix.Download(url)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
debug.Printf("Failed to download %s: %v", url, err)
|
debug.Printf("Failed to download %s: %v", evt.Content.URL, err)
|
||||||
}
|
}
|
||||||
return messages.NewImageMessage(matrix, evt.ID, evt.Sender, displayname, msgtype, text, hs, id, data, ts)
|
return messages.NewImageMessage(matrix, evt.ID, evt.Sender, displayname, evt.Content.MsgType, evt.Content.Body, hs, id, data, ts)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMembershipChangeMessage(evt *gomatrix.Event, membership, prevMembership, senderDisplayname, displayname, prevDisplayname string) (sender string, text tstring.TString) {
|
func getMembershipChangeMessage(evt *gomatrix.Event, membership, prevMembership gomatrix.Membership, senderDisplayname, displayname, prevDisplayname string) (sender string, text tstring.TString) {
|
||||||
switch membership {
|
switch membership {
|
||||||
case "invite":
|
case "invite":
|
||||||
sender = "---"
|
sender = "---"
|
||||||
@ -92,12 +88,11 @@ func getMembershipChangeMessage(evt *gomatrix.Event, membership, prevMembership,
|
|||||||
case "leave":
|
case "leave":
|
||||||
sender = "<--"
|
sender = "<--"
|
||||||
if evt.Sender != *evt.StateKey {
|
if evt.Sender != *evt.StateKey {
|
||||||
if prevMembership == "ban" {
|
if prevMembership == gomatrix.MembershipBan {
|
||||||
text = tstring.NewColorTString(fmt.Sprintf("%s unbanned %s", senderDisplayname, displayname), tcell.ColorGreen)
|
text = tstring.NewColorTString(fmt.Sprintf("%s unbanned %s", senderDisplayname, displayname), tcell.ColorGreen)
|
||||||
text.Colorize(len(senderDisplayname)+len(" unbanned "), len(displayname), widget.GetHashColor(*evt.StateKey))
|
text.Colorize(len(senderDisplayname)+len(" unbanned "), len(displayname), widget.GetHashColor(*evt.StateKey))
|
||||||
} else {
|
} else {
|
||||||
reason, _ := evt.Content["reason"].(string)
|
text = tstring.NewColorTString(fmt.Sprintf("%s kicked %s: %s", senderDisplayname, displayname, evt.Content.Reason), tcell.ColorRed)
|
||||||
text = tstring.NewColorTString(fmt.Sprintf("%s kicked %s: %s", senderDisplayname, displayname, reason), tcell.ColorRed)
|
|
||||||
text.Colorize(len(senderDisplayname)+len(" kicked "), len(displayname), widget.GetHashColor(*evt.StateKey))
|
text.Colorize(len(senderDisplayname)+len(" kicked "), len(displayname), widget.GetHashColor(*evt.StateKey))
|
||||||
}
|
}
|
||||||
text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender))
|
text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender))
|
||||||
@ -109,8 +104,7 @@ func getMembershipChangeMessage(evt *gomatrix.Event, membership, prevMembership,
|
|||||||
text.Colorize(0, len(displayname), widget.GetHashColor(*evt.StateKey))
|
text.Colorize(0, len(displayname), widget.GetHashColor(*evt.StateKey))
|
||||||
}
|
}
|
||||||
case "ban":
|
case "ban":
|
||||||
reason, _ := evt.Content["reason"].(string)
|
text = tstring.NewColorTString(fmt.Sprintf("%s banned %s: %s", senderDisplayname, displayname, evt.Content.Reason), tcell.ColorRed)
|
||||||
text = tstring.NewColorTString(fmt.Sprintf("%s banned %s: %s", senderDisplayname, displayname, reason), tcell.ColorRed)
|
|
||||||
text.Colorize(len(senderDisplayname)+len(" banned "), len(displayname), widget.GetHashColor(*evt.StateKey))
|
text.Colorize(len(senderDisplayname)+len(" banned "), len(displayname), widget.GetHashColor(*evt.StateKey))
|
||||||
text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender))
|
text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender))
|
||||||
}
|
}
|
||||||
@ -121,20 +115,20 @@ func getMembershipEventContent(room *rooms.Room, evt *gomatrix.Event) (sender st
|
|||||||
member := room.GetMember(evt.Sender)
|
member := room.GetMember(evt.Sender)
|
||||||
senderDisplayname := evt.Sender
|
senderDisplayname := evt.Sender
|
||||||
if member != nil {
|
if member != nil {
|
||||||
senderDisplayname = member.DisplayName
|
senderDisplayname = member.Displayname
|
||||||
}
|
}
|
||||||
|
|
||||||
membership, _ := evt.Content["membership"].(string)
|
membership := evt.Content.Membership
|
||||||
displayname, _ := evt.Content["displayname"].(string)
|
displayname := evt.Content.Displayname
|
||||||
if len(displayname) == 0 {
|
if len(displayname) == 0 {
|
||||||
displayname = *evt.StateKey
|
displayname = *evt.StateKey
|
||||||
}
|
}
|
||||||
|
|
||||||
prevMembership := "leave"
|
prevMembership := gomatrix.MembershipLeave
|
||||||
prevDisplayname := *evt.StateKey
|
prevDisplayname := *evt.StateKey
|
||||||
if evt.Unsigned.PrevContent != nil {
|
if evt.Unsigned.PrevContent != nil {
|
||||||
prevMembership, _ = evt.Unsigned.PrevContent["membership"].(string)
|
prevMembership = evt.Unsigned.PrevContent.Membership
|
||||||
prevDisplayname, _ = evt.Unsigned.PrevContent["displayname"].(string)
|
prevDisplayname = evt.Unsigned.PrevContent.Displayname
|
||||||
if len(prevDisplayname) == 0 {
|
if len(prevDisplayname) == 0 {
|
||||||
prevDisplayname = *evt.StateKey
|
prevDisplayname = *evt.StateKey
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package messages
|
|||||||
import (
|
import (
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maunium.net/go/gomatrix"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"maunium.net/go/gomuks/config"
|
"maunium.net/go/gomuks/config"
|
||||||
@ -37,7 +38,7 @@ type TextMessage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewTextMessage creates a new UITextMessage object with the provided values and the default state.
|
// NewTextMessage creates a new UITextMessage object with the provided values and the default state.
|
||||||
func NewTextMessage(id, sender, displayname, msgtype, text string, timestamp time.Time) UIMessage {
|
func NewTextMessage(id, sender, displayname string, msgtype gomatrix.MessageType, text string, timestamp time.Time) UIMessage {
|
||||||
return &TextMessage{
|
return &TextMessage{
|
||||||
BaseMessage: newBaseMessage(id, sender, displayname, msgtype, timestamp),
|
BaseMessage: newBaseMessage(id, sender, displayname, msgtype, timestamp),
|
||||||
MsgText: text,
|
MsgText: text,
|
||||||
@ -57,7 +58,7 @@ func (msg *TextMessage) getCache() tstring.TString {
|
|||||||
return msg.cache
|
return msg.cache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *TextMessage) SetType(msgtype string) {
|
func (msg *TextMessage) SetType(msgtype gomatrix.MessageType) {
|
||||||
msg.BaseMessage.SetType(msgtype)
|
msg.BaseMessage.SetType(msgtype)
|
||||||
msg.cache = nil
|
msg.cache = nil
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package ui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maunium.net/go/gomatrix"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -242,7 +243,7 @@ func (view *RoomView) SetTyping(users []string) {
|
|||||||
for index, user := range users {
|
for index, user := range users {
|
||||||
member := view.Room.GetMember(user)
|
member := view.Room.GetMember(user)
|
||||||
if member != nil {
|
if member != nil {
|
||||||
users[index] = member.DisplayName
|
users[index] = member.Displayname
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
view.typing = users
|
view.typing = users
|
||||||
@ -255,14 +256,14 @@ type completion struct {
|
|||||||
|
|
||||||
func (view *RoomView) autocompleteUser(existingText string) (completions []completion) {
|
func (view *RoomView) autocompleteUser(existingText string) (completions []completion) {
|
||||||
textWithoutPrefix := strings.TrimPrefix(existingText, "@")
|
textWithoutPrefix := strings.TrimPrefix(existingText, "@")
|
||||||
for _, user := range view.Room.GetMembers() {
|
for userID, user := range view.Room.GetMembers() {
|
||||||
if user.DisplayName == textWithoutPrefix || user.UserID == existingText {
|
if user.Displayname == textWithoutPrefix || userID == existingText {
|
||||||
// Exact match, return that.
|
// Exact match, return that.
|
||||||
return []completion{{user.DisplayName, user.UserID}}
|
return []completion{{user.Displayname, userID}}
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(user.DisplayName, textWithoutPrefix) || strings.HasPrefix(user.UserID, existingText) {
|
if strings.HasPrefix(user.Displayname, textWithoutPrefix) || strings.HasPrefix(userID, existingText) {
|
||||||
completions = append(completions, completion{user.DisplayName, user.UserID})
|
completions = append(completions, completion{user.Displayname, userID})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -330,12 +331,12 @@ func (view *RoomView) MxRoom() *rooms.Room {
|
|||||||
func (view *RoomView) UpdateUserList() {
|
func (view *RoomView) UpdateUserList() {
|
||||||
var joined strings.Builder
|
var joined strings.Builder
|
||||||
var invited strings.Builder
|
var invited strings.Builder
|
||||||
for _, user := range view.Room.GetMembers() {
|
for userID, user := range view.Room.GetMembers() {
|
||||||
if user.Membership == "join" {
|
if user.Membership == "join" {
|
||||||
joined.WriteString(widget.AddColor(user.DisplayName, widget.GetHashColorName(user.UserID)))
|
joined.WriteString(widget.AddColor(user.Displayname, widget.GetHashColorName(userID)))
|
||||||
joined.WriteRune('\n')
|
joined.WriteRune('\n')
|
||||||
} else if user.Membership == "invite" {
|
} else if user.Membership == "invite" {
|
||||||
invited.WriteString(widget.AddColor(user.DisplayName, widget.GetHashColorName(user.UserID)))
|
invited.WriteString(widget.AddColor(user.Displayname, widget.GetHashColorName(userID)))
|
||||||
invited.WriteRune('\n')
|
invited.WriteRune('\n')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -346,26 +347,26 @@ func (view *RoomView) UpdateUserList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *RoomView) newUIMessage(id, sender, msgtype, text string, timestamp time.Time) messages.UIMessage {
|
func (view *RoomView) newUIMessage(id, sender string, msgtype gomatrix.MessageType, text string, timestamp time.Time) messages.UIMessage {
|
||||||
member := view.Room.GetMember(sender)
|
member := view.Room.GetMember(sender)
|
||||||
displayname := sender
|
displayname := sender
|
||||||
if member != nil {
|
if member != nil {
|
||||||
displayname = member.DisplayName
|
displayname = member.Displayname
|
||||||
}
|
}
|
||||||
msg := messages.NewTextMessage(id, sender, displayname, msgtype, text, timestamp)
|
msg := messages.NewTextMessage(id, sender, displayname, msgtype, text, timestamp)
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *RoomView) NewMessage(id, sender, msgtype, text string, timestamp time.Time) ifc.Message {
|
func (view *RoomView) NewMessage(id, sender string, msgtype gomatrix.MessageType, text string, timestamp time.Time) ifc.Message {
|
||||||
return view.newUIMessage(id, sender, msgtype, text, timestamp)
|
return view.newUIMessage(id, sender, msgtype, text, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *RoomView) NewTempMessage(msgtype, text string) ifc.Message {
|
func (view *RoomView) NewTempMessage(msgtype gomatrix.MessageType, text string) ifc.Message {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
id := strconv.FormatInt(now.UnixNano(), 10)
|
id := strconv.FormatInt(now.UnixNano(), 10)
|
||||||
sender := ""
|
sender := ""
|
||||||
if ownerMember := view.Room.GetSessionOwner(); ownerMember != nil {
|
if ownerMember := view.Room.GetMember(view.Room.GetSessionOwner()); ownerMember != nil {
|
||||||
sender = ownerMember.DisplayName
|
sender = ownerMember.Displayname
|
||||||
}
|
}
|
||||||
message := view.newUIMessage(id, sender, msgtype, text, now)
|
message := view.newUIMessage(id, sender, msgtype, text, now)
|
||||||
message.SetState(ifc.MessageStateSending)
|
message.SetState(ifc.MessageStateSending)
|
||||||
|
@ -497,7 +497,7 @@ func (view *MainView) LoadHistory(room string) {
|
|||||||
}
|
}
|
||||||
roomView.Room.PrevBatch = prevBatch
|
roomView.Room.PrevBatch = prevBatch
|
||||||
for _, evt := range history {
|
for _, evt := range history {
|
||||||
message := view.ParseEvent(roomView, &evt)
|
message := view.ParseEvent(roomView, evt)
|
||||||
if message != nil {
|
if message != nil {
|
||||||
roomView.AddMessage(message, ifc.PrependMessage)
|
roomView.AddMessage(message, ifc.PrependMessage)
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
2
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
@ -2,7 +2,7 @@ ISC License
|
|||||||
|
|
||||||
Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
|
Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
|
||||||
|
|
||||||
Permission to use, copy, modify, and distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
copyright notice and this permission notice appear in all copies.
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
187
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
187
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
@ -16,7 +16,9 @@
|
|||||||
// when the code is not running on Google App Engine, compiled by GopherJS, and
|
// when the code is not running on Google App Engine, compiled by GopherJS, and
|
||||||
// "-tags safe" is not added to the go build command line. The "disableunsafe"
|
// "-tags safe" is not added to the go build command line. The "disableunsafe"
|
||||||
// tag is deprecated and thus should not be used.
|
// tag is deprecated and thus should not be used.
|
||||||
// +build !js,!appengine,!safe,!disableunsafe
|
// Go versions prior to 1.4 are disabled because they use a different layout
|
||||||
|
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
||||||
|
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
||||||
|
|
||||||
package spew
|
package spew
|
||||||
|
|
||||||
@ -34,80 +36,49 @@ const (
|
|||||||
ptrSize = unsafe.Sizeof((*byte)(nil))
|
ptrSize = unsafe.Sizeof((*byte)(nil))
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
type flag uintptr
|
||||||
// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
|
|
||||||
// internal reflect.Value fields. These values are valid before golang
|
|
||||||
// commit ecccf07e7f9d which changed the format. The are also valid
|
|
||||||
// after commit 82f48826c6c7 which changed the format again to mirror
|
|
||||||
// the original format. Code in the init function updates these offsets
|
|
||||||
// as necessary.
|
|
||||||
offsetPtr = uintptr(ptrSize)
|
|
||||||
offsetScalar = uintptr(0)
|
|
||||||
offsetFlag = uintptr(ptrSize * 2)
|
|
||||||
|
|
||||||
// flagKindWidth and flagKindShift indicate various bits that the
|
var (
|
||||||
// reflect package uses internally to track kind information.
|
// flagRO indicates whether the value field of a reflect.Value
|
||||||
//
|
// is read-only.
|
||||||
// flagRO indicates whether or not the value field of a reflect.Value is
|
flagRO flag
|
||||||
// read-only.
|
|
||||||
//
|
// flagAddr indicates whether the address of the reflect.Value's
|
||||||
// flagIndir indicates whether the value field of a reflect.Value is
|
// value may be taken.
|
||||||
// the actual data or a pointer to the data.
|
flagAddr flag
|
||||||
//
|
|
||||||
// These values are valid before golang commit 90a7c3c86944 which
|
|
||||||
// changed their positions. Code in the init function updates these
|
|
||||||
// flags as necessary.
|
|
||||||
flagKindWidth = uintptr(5)
|
|
||||||
flagKindShift = uintptr(flagKindWidth - 1)
|
|
||||||
flagRO = uintptr(1 << 0)
|
|
||||||
flagIndir = uintptr(1 << 1)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
// flagKindMask holds the bits that make up the kind
|
||||||
// Older versions of reflect.Value stored small integers directly in the
|
// part of the flags field. In all the supported versions,
|
||||||
// ptr field (which is named val in the older versions). Versions
|
// it is in the lower 5 bits.
|
||||||
// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
|
const flagKindMask = flag(0x1f)
|
||||||
// scalar for this purpose which unfortunately came before the flag
|
|
||||||
// field, so the offset of the flag field is different for those
|
|
||||||
// versions.
|
|
||||||
//
|
|
||||||
// This code constructs a new reflect.Value from a known small integer
|
|
||||||
// and checks if the size of the reflect.Value struct indicates it has
|
|
||||||
// the scalar field. When it does, the offsets are updated accordingly.
|
|
||||||
vv := reflect.ValueOf(0xf00)
|
|
||||||
if unsafe.Sizeof(vv) == (ptrSize * 4) {
|
|
||||||
offsetScalar = ptrSize * 2
|
|
||||||
offsetFlag = ptrSize * 3
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commit 90a7c3c86944 changed the flag positions such that the low
|
// Different versions of Go have used different
|
||||||
// order bits are the kind. This code extracts the kind from the flags
|
// bit layouts for the flags type. This table
|
||||||
// field and ensures it's the correct type. When it's not, the flag
|
// records the known combinations.
|
||||||
// order has been changed to the newer format, so the flags are updated
|
var okFlags = []struct {
|
||||||
// accordingly.
|
ro, addr flag
|
||||||
upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
|
}{{
|
||||||
upfv := *(*uintptr)(upf)
|
// From Go 1.4 to 1.5
|
||||||
flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
|
ro: 1 << 5,
|
||||||
if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
|
addr: 1 << 7,
|
||||||
flagKindShift = 0
|
}, {
|
||||||
flagRO = 1 << 5
|
// Up to Go tip.
|
||||||
flagIndir = 1 << 6
|
ro: 1<<5 | 1<<6,
|
||||||
|
addr: 1 << 8,
|
||||||
|
}}
|
||||||
|
|
||||||
// Commit adf9b30e5594 modified the flags to separate the
|
var flagValOffset = func() uintptr {
|
||||||
// flagRO flag into two bits which specifies whether or not the
|
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||||
// field is embedded. This causes flagIndir to move over a bit
|
if !ok {
|
||||||
// and means that flagRO is the combination of either of the
|
panic("reflect.Value has no flag field")
|
||||||
// original flagRO bit and the new bit.
|
|
||||||
//
|
|
||||||
// This code detects the change by extracting what used to be
|
|
||||||
// the indirect bit to ensure it's set. When it's not, the flag
|
|
||||||
// order has been changed to the newer format, so the flags are
|
|
||||||
// updated accordingly.
|
|
||||||
if upfv&flagIndir == 0 {
|
|
||||||
flagRO = 3 << 5
|
|
||||||
flagIndir = 1 << 7
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return field.Offset
|
||||||
|
}()
|
||||||
|
|
||||||
|
// flagField returns a pointer to the flag field of a reflect.Value.
|
||||||
|
func flagField(v *reflect.Value) *flag {
|
||||||
|
return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
||||||
@ -119,34 +90,56 @@ func init() {
|
|||||||
// This allows us to check for implementations of the Stringer and error
|
// This allows us to check for implementations of the Stringer and error
|
||||||
// interfaces to be used for pretty printing ordinarily unaddressable and
|
// interfaces to be used for pretty printing ordinarily unaddressable and
|
||||||
// inaccessible values such as unexported struct fields.
|
// inaccessible values such as unexported struct fields.
|
||||||
func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
|
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
||||||
indirects := 1
|
if !v.IsValid() || (v.CanInterface() && v.CanAddr()) {
|
||||||
vt := v.Type()
|
return v
|
||||||
upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
|
}
|
||||||
rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
|
flagFieldPtr := flagField(&v)
|
||||||
if rvf&flagIndir != 0 {
|
*flagFieldPtr &^= flagRO
|
||||||
vt = reflect.PtrTo(v.Type())
|
*flagFieldPtr |= flagAddr
|
||||||
indirects++
|
return v
|
||||||
} else if offsetScalar != 0 {
|
}
|
||||||
// The value is in the scalar field when it's not one of the
|
|
||||||
// reference types.
|
// Sanity checks against future reflect package changes
|
||||||
switch vt.Kind() {
|
// to the type or semantics of the Value.flag field.
|
||||||
case reflect.Uintptr:
|
func init() {
|
||||||
case reflect.Chan:
|
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||||
case reflect.Func:
|
if !ok {
|
||||||
case reflect.Map:
|
panic("reflect.Value has no flag field")
|
||||||
case reflect.Ptr:
|
}
|
||||||
case reflect.UnsafePointer:
|
if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
|
||||||
default:
|
panic("reflect.Value flag field has changed kind")
|
||||||
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
|
}
|
||||||
offsetScalar)
|
type t0 int
|
||||||
|
var t struct {
|
||||||
|
A t0
|
||||||
|
// t0 will have flagEmbedRO set.
|
||||||
|
t0
|
||||||
|
// a will have flagStickyRO set
|
||||||
|
a t0
|
||||||
|
}
|
||||||
|
vA := reflect.ValueOf(t).FieldByName("A")
|
||||||
|
va := reflect.ValueOf(t).FieldByName("a")
|
||||||
|
vt0 := reflect.ValueOf(t).FieldByName("t0")
|
||||||
|
|
||||||
|
// Infer flagRO from the difference between the flags
|
||||||
|
// for the (otherwise identical) fields in t.
|
||||||
|
flagPublic := *flagField(&vA)
|
||||||
|
flagWithRO := *flagField(&va) | *flagField(&vt0)
|
||||||
|
flagRO = flagPublic ^ flagWithRO
|
||||||
|
|
||||||
|
// Infer flagAddr from the difference between a value
|
||||||
|
// taken from a pointer and not.
|
||||||
|
vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A")
|
||||||
|
flagNoPtr := *flagField(&vA)
|
||||||
|
flagPtr := *flagField(&vPtrA)
|
||||||
|
flagAddr = flagNoPtr ^ flagPtr
|
||||||
|
|
||||||
|
// Check that the inferred flags tally with one of the known versions.
|
||||||
|
for _, f := range okFlags {
|
||||||
|
if flagRO == f.ro && flagAddr == f.addr {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
panic("reflect.Value read-only flag has changed semantics")
|
||||||
pv := reflect.NewAt(vt, upv)
|
|
||||||
rv = pv
|
|
||||||
for i := 0; i < indirects; i++ {
|
|
||||||
rv = rv.Elem()
|
|
||||||
}
|
|
||||||
return rv
|
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
2
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
@ -16,7 +16,7 @@
|
|||||||
// when the code is running on Google App Engine, compiled by GopherJS, or
|
// when the code is running on Google App Engine, compiled by GopherJS, or
|
||||||
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
||||||
// tag is deprecated and thus should not be used.
|
// tag is deprecated and thus should not be used.
|
||||||
// +build js appengine safe disableunsafe
|
// +build js appengine safe disableunsafe !go1.4
|
||||||
|
|
||||||
package spew
|
package spew
|
||||||
|
|
||||||
|
2
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
2
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
@ -180,7 +180,7 @@ func printComplex(w io.Writer, c complex128, floatPrecision int) {
|
|||||||
w.Write(closeParenBytes)
|
w.Write(closeParenBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
|
// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'
|
||||||
// prefix to Writer w.
|
// prefix to Writer w.
|
||||||
func printHexPtr(w io.Writer, p uintptr) {
|
func printHexPtr(w io.Writer, p uintptr) {
|
||||||
// Null pointer.
|
// Null pointer.
|
||||||
|
10
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
10
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
@ -35,16 +35,16 @@ var (
|
|||||||
|
|
||||||
// cCharRE is a regular expression that matches a cgo char.
|
// cCharRE is a regular expression that matches a cgo char.
|
||||||
// It is used to detect character arrays to hexdump them.
|
// It is used to detect character arrays to hexdump them.
|
||||||
cCharRE = regexp.MustCompile("^.*\\._Ctype_char$")
|
cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`)
|
||||||
|
|
||||||
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
|
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
|
||||||
// char. It is used to detect unsigned character arrays to hexdump
|
// char. It is used to detect unsigned character arrays to hexdump
|
||||||
// them.
|
// them.
|
||||||
cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$")
|
cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`)
|
||||||
|
|
||||||
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
|
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
|
||||||
// It is used to detect uint8_t arrays to hexdump them.
|
// It is used to detect uint8_t arrays to hexdump them.
|
||||||
cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$")
|
cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
// dumpState contains information about the state of a dump operation.
|
// dumpState contains information about the state of a dump operation.
|
||||||
@ -143,10 +143,10 @@ func (d *dumpState) dumpPtr(v reflect.Value) {
|
|||||||
// Display dereferenced value.
|
// Display dereferenced value.
|
||||||
d.w.Write(openParenBytes)
|
d.w.Write(openParenBytes)
|
||||||
switch {
|
switch {
|
||||||
case nilFound == true:
|
case nilFound:
|
||||||
d.w.Write(nilAngleBytes)
|
d.w.Write(nilAngleBytes)
|
||||||
|
|
||||||
case cycleFound == true:
|
case cycleFound:
|
||||||
d.w.Write(circularBytes)
|
d.w.Write(circularBytes)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
4
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
4
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
@ -182,10 +182,10 @@ func (f *formatState) formatPtr(v reflect.Value) {
|
|||||||
|
|
||||||
// Display dereferenced value.
|
// Display dereferenced value.
|
||||||
switch {
|
switch {
|
||||||
case nilFound == true:
|
case nilFound:
|
||||||
f.fs.Write(nilAngleBytes)
|
f.fs.Write(nilAngleBytes)
|
||||||
|
|
||||||
case cycleFound == true:
|
case cycleFound:
|
||||||
f.fs.Write(circularShortBytes)
|
f.fs.Write(circularShortBytes)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
36
vendor/github.com/disintegration/imaging/effects.go
generated
vendored
36
vendor/github.com/disintegration/imaging/effects.go
generated
vendored
@ -38,9 +38,13 @@ func blurHorizontal(img image.Image, kernel []float64) *image.NRGBA {
|
|||||||
|
|
||||||
parallel(0, src.h, func(ys <-chan int) {
|
parallel(0, src.h, func(ys <-chan int) {
|
||||||
scanLine := make([]uint8, src.w*4)
|
scanLine := make([]uint8, src.w*4)
|
||||||
|
scanLineF := make([]float64, len(scanLine))
|
||||||
for y := range ys {
|
for y := range ys {
|
||||||
src.scan(0, y, src.w, y+1, scanLine)
|
src.scan(0, y, src.w, y+1, scanLine)
|
||||||
for x := 0; x < src.w; x++ {
|
for i, v := range scanLine {
|
||||||
|
scanLineF[i] = float64(v)
|
||||||
|
}
|
||||||
|
for x, idx := 0, 0; x < src.w; x, idx = x+1, idx+4 {
|
||||||
min := x - radius
|
min := x - radius
|
||||||
if min < 0 {
|
if min < 0 {
|
||||||
min = 0
|
min = 0
|
||||||
@ -55,10 +59,10 @@ func blurHorizontal(img image.Image, kernel []float64) *image.NRGBA {
|
|||||||
i := ix * 4
|
i := ix * 4
|
||||||
weight := kernel[absint(x-ix)]
|
weight := kernel[absint(x-ix)]
|
||||||
wsum += weight
|
wsum += weight
|
||||||
wa := float64(scanLine[i+3]) * weight
|
wa := scanLineF[i+3] * weight
|
||||||
r += float64(scanLine[i+0]) * wa
|
r += scanLineF[i+0] * wa
|
||||||
g += float64(scanLine[i+1]) * wa
|
g += scanLineF[i+1] * wa
|
||||||
b += float64(scanLine[i+2]) * wa
|
b += scanLineF[i+2] * wa
|
||||||
a += wa
|
a += wa
|
||||||
}
|
}
|
||||||
if a != 0 {
|
if a != 0 {
|
||||||
@ -67,12 +71,12 @@ func blurHorizontal(img image.Image, kernel []float64) *image.NRGBA {
|
|||||||
b /= a
|
b /= a
|
||||||
}
|
}
|
||||||
|
|
||||||
j := y*dst.Stride + x*4
|
scanLine[idx+0] = clamp(r)
|
||||||
dst.Pix[j+0] = clamp(r)
|
scanLine[idx+1] = clamp(g)
|
||||||
dst.Pix[j+1] = clamp(g)
|
scanLine[idx+2] = clamp(b)
|
||||||
dst.Pix[j+2] = clamp(b)
|
scanLine[idx+3] = clamp(a / wsum)
|
||||||
dst.Pix[j+3] = clamp(a / wsum)
|
|
||||||
}
|
}
|
||||||
|
copy(dst.Pix[y*dst.Stride:], scanLine)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -86,8 +90,12 @@ func blurVertical(img image.Image, kernel []float64) *image.NRGBA {
|
|||||||
|
|
||||||
parallel(0, src.w, func(xs <-chan int) {
|
parallel(0, src.w, func(xs <-chan int) {
|
||||||
scanLine := make([]uint8, src.h*4)
|
scanLine := make([]uint8, src.h*4)
|
||||||
|
scanLineF := make([]float64, len(scanLine))
|
||||||
for x := range xs {
|
for x := range xs {
|
||||||
src.scan(x, 0, x+1, src.h, scanLine)
|
src.scan(x, 0, x+1, src.h, scanLine)
|
||||||
|
for i, v := range scanLine {
|
||||||
|
scanLineF[i] = float64(v)
|
||||||
|
}
|
||||||
for y := 0; y < src.h; y++ {
|
for y := 0; y < src.h; y++ {
|
||||||
min := y - radius
|
min := y - radius
|
||||||
if min < 0 {
|
if min < 0 {
|
||||||
@ -103,10 +111,10 @@ func blurVertical(img image.Image, kernel []float64) *image.NRGBA {
|
|||||||
i := iy * 4
|
i := iy * 4
|
||||||
weight := kernel[absint(y-iy)]
|
weight := kernel[absint(y-iy)]
|
||||||
wsum += weight
|
wsum += weight
|
||||||
wa := float64(scanLine[i+3]) * weight
|
wa := scanLineF[i+3] * weight
|
||||||
r += float64(scanLine[i+0]) * wa
|
r += scanLineF[i+0] * wa
|
||||||
g += float64(scanLine[i+1]) * wa
|
g += scanLineF[i+1] * wa
|
||||||
b += float64(scanLine[i+2]) * wa
|
b += scanLineF[i+2] * wa
|
||||||
a += wa
|
a += wa
|
||||||
}
|
}
|
||||||
if a != 0 {
|
if a != 0 {
|
||||||
|
272
vendor/github.com/disintegration/imaging/helpers.go
generated
vendored
272
vendor/github.com/disintegration/imaging/helpers.go
generated
vendored
@ -1,272 +0,0 @@
|
|||||||
package imaging
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"image"
|
|
||||||
"image/color"
|
|
||||||
"image/draw"
|
|
||||||
"image/gif"
|
|
||||||
"image/jpeg"
|
|
||||||
"image/png"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/image/bmp"
|
|
||||||
"golang.org/x/image/tiff"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Format is an image file format.
|
|
||||||
type Format int
|
|
||||||
|
|
||||||
// Image file formats.
|
|
||||||
const (
|
|
||||||
JPEG Format = iota
|
|
||||||
PNG
|
|
||||||
GIF
|
|
||||||
TIFF
|
|
||||||
BMP
|
|
||||||
)
|
|
||||||
|
|
||||||
func (f Format) String() string {
|
|
||||||
switch f {
|
|
||||||
case JPEG:
|
|
||||||
return "JPEG"
|
|
||||||
case PNG:
|
|
||||||
return "PNG"
|
|
||||||
case GIF:
|
|
||||||
return "GIF"
|
|
||||||
case TIFF:
|
|
||||||
return "TIFF"
|
|
||||||
case BMP:
|
|
||||||
return "BMP"
|
|
||||||
default:
|
|
||||||
return "Unsupported"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var formatFromExt = map[string]Format{
|
|
||||||
".jpg": JPEG,
|
|
||||||
".jpeg": JPEG,
|
|
||||||
".png": PNG,
|
|
||||||
".tif": TIFF,
|
|
||||||
".tiff": TIFF,
|
|
||||||
".bmp": BMP,
|
|
||||||
".gif": GIF,
|
|
||||||
}
|
|
||||||
|
|
||||||
// FormatFromFilename parses image format from filename extension:
|
|
||||||
// "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
|
|
||||||
func FormatFromFilename(filename string) (Format, error) {
|
|
||||||
ext := strings.ToLower(filepath.Ext(filename))
|
|
||||||
if f, ok := formatFromExt[ext]; ok {
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
return -1, ErrUnsupportedFormat
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrUnsupportedFormat means the given image format (or file extension) is unsupported.
|
|
||||||
ErrUnsupportedFormat = errors.New("imaging: unsupported image format")
|
|
||||||
)
|
|
||||||
|
|
||||||
type fileSystem interface {
|
|
||||||
Create(string) (io.WriteCloser, error)
|
|
||||||
Open(string) (io.ReadCloser, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type localFS struct{}
|
|
||||||
|
|
||||||
func (localFS) Create(name string) (io.WriteCloser, error) { return os.Create(name) }
|
|
||||||
func (localFS) Open(name string) (io.ReadCloser, error) { return os.Open(name) }
|
|
||||||
|
|
||||||
var fs fileSystem = localFS{}
|
|
||||||
|
|
||||||
// Decode reads an image from r.
|
|
||||||
func Decode(r io.Reader) (image.Image, error) {
|
|
||||||
img, _, err := image.Decode(r)
|
|
||||||
return img, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open loads an image from file
|
|
||||||
func Open(filename string) (image.Image, error) {
|
|
||||||
file, err := fs.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
return Decode(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
type encodeConfig struct {
|
|
||||||
jpegQuality int
|
|
||||||
gifNumColors int
|
|
||||||
gifQuantizer draw.Quantizer
|
|
||||||
gifDrawer draw.Drawer
|
|
||||||
pngCompressionLevel png.CompressionLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultEncodeConfig = encodeConfig{
|
|
||||||
jpegQuality: 95,
|
|
||||||
gifNumColors: 256,
|
|
||||||
gifQuantizer: nil,
|
|
||||||
gifDrawer: nil,
|
|
||||||
pngCompressionLevel: png.DefaultCompression,
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeOption sets an optional parameter for the Encode and Save functions.
|
|
||||||
type EncodeOption func(*encodeConfig)
|
|
||||||
|
|
||||||
// JPEGQuality returns an EncodeOption that sets the output JPEG quality.
|
|
||||||
// Quality ranges from 1 to 100 inclusive, higher is better. Default is 95.
|
|
||||||
func JPEGQuality(quality int) EncodeOption {
|
|
||||||
return func(c *encodeConfig) {
|
|
||||||
c.jpegQuality = quality
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GIFNumColors returns an EncodeOption that sets the maximum number of colors
|
|
||||||
// used in the GIF-encoded image. It ranges from 1 to 256. Default is 256.
|
|
||||||
func GIFNumColors(numColors int) EncodeOption {
|
|
||||||
return func(c *encodeConfig) {
|
|
||||||
c.gifNumColors = numColors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GIFQuantizer returns an EncodeOption that sets the quantizer that is used to produce
|
|
||||||
// a palette of the GIF-encoded image.
|
|
||||||
func GIFQuantizer(quantizer draw.Quantizer) EncodeOption {
|
|
||||||
return func(c *encodeConfig) {
|
|
||||||
c.gifQuantizer = quantizer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GIFDrawer returns an EncodeOption that sets the drawer that is used to convert
|
|
||||||
// the source image to the desired palette of the GIF-encoded image.
|
|
||||||
func GIFDrawer(drawer draw.Drawer) EncodeOption {
|
|
||||||
return func(c *encodeConfig) {
|
|
||||||
c.gifDrawer = drawer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PNGCompressionLevel returns an EncodeOption that sets the compression level
|
|
||||||
// of the PNG-encoded image. Default is png.DefaultCompression.
|
|
||||||
func PNGCompressionLevel(level png.CompressionLevel) EncodeOption {
|
|
||||||
return func(c *encodeConfig) {
|
|
||||||
c.pngCompressionLevel = level
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode writes the image img to w in the specified format (JPEG, PNG, GIF, TIFF or BMP).
|
|
||||||
func Encode(w io.Writer, img image.Image, format Format, opts ...EncodeOption) error {
|
|
||||||
cfg := defaultEncodeConfig
|
|
||||||
for _, option := range opts {
|
|
||||||
option(&cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
switch format {
|
|
||||||
case JPEG:
|
|
||||||
var rgba *image.RGBA
|
|
||||||
if nrgba, ok := img.(*image.NRGBA); ok {
|
|
||||||
if nrgba.Opaque() {
|
|
||||||
rgba = &image.RGBA{
|
|
||||||
Pix: nrgba.Pix,
|
|
||||||
Stride: nrgba.Stride,
|
|
||||||
Rect: nrgba.Rect,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if rgba != nil {
|
|
||||||
err = jpeg.Encode(w, rgba, &jpeg.Options{Quality: cfg.jpegQuality})
|
|
||||||
} else {
|
|
||||||
err = jpeg.Encode(w, img, &jpeg.Options{Quality: cfg.jpegQuality})
|
|
||||||
}
|
|
||||||
|
|
||||||
case PNG:
|
|
||||||
enc := png.Encoder{CompressionLevel: cfg.pngCompressionLevel}
|
|
||||||
err = enc.Encode(w, img)
|
|
||||||
|
|
||||||
case GIF:
|
|
||||||
err = gif.Encode(w, img, &gif.Options{
|
|
||||||
NumColors: cfg.gifNumColors,
|
|
||||||
Quantizer: cfg.gifQuantizer,
|
|
||||||
Drawer: cfg.gifDrawer,
|
|
||||||
})
|
|
||||||
|
|
||||||
case TIFF:
|
|
||||||
err = tiff.Encode(w, img, &tiff.Options{Compression: tiff.Deflate, Predictor: true})
|
|
||||||
|
|
||||||
case BMP:
|
|
||||||
err = bmp.Encode(w, img)
|
|
||||||
|
|
||||||
default:
|
|
||||||
err = ErrUnsupportedFormat
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save saves the image to file with the specified filename.
|
|
||||||
// The format is determined from the filename extension: "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
|
|
||||||
//
|
|
||||||
// Examples:
|
|
||||||
//
|
|
||||||
// // Save the image as PNG.
|
|
||||||
// err := imaging.Save(img, "out.png")
|
|
||||||
//
|
|
||||||
// // Save the image as JPEG with optional quality parameter set to 80.
|
|
||||||
// err := imaging.Save(img, "out.jpg", imaging.JPEGQuality(80))
|
|
||||||
//
|
|
||||||
func Save(img image.Image, filename string, opts ...EncodeOption) (err error) {
|
|
||||||
f, err := FormatFromFilename(filename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
file, err := fs.Create(filename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
cerr := file.Close()
|
|
||||||
if err == nil {
|
|
||||||
err = cerr
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return Encode(file, img, f, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new image with the specified width and height, and fills it with the specified color.
|
|
||||||
func New(width, height int, fillColor color.Color) *image.NRGBA {
|
|
||||||
if width <= 0 || height <= 0 {
|
|
||||||
return &image.NRGBA{}
|
|
||||||
}
|
|
||||||
|
|
||||||
c := color.NRGBAModel.Convert(fillColor).(color.NRGBA)
|
|
||||||
if (c == color.NRGBA{0, 0, 0, 0}) {
|
|
||||||
return image.NewNRGBA(image.Rect(0, 0, width, height))
|
|
||||||
}
|
|
||||||
|
|
||||||
return &image.NRGBA{
|
|
||||||
Pix: bytes.Repeat([]byte{c.R, c.G, c.B, c.A}, width*height),
|
|
||||||
Stride: 4 * width,
|
|
||||||
Rect: image.Rect(0, 0, width, height),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clone returns a copy of the given image.
|
|
||||||
func Clone(img image.Image) *image.NRGBA {
|
|
||||||
src := newScanner(img)
|
|
||||||
dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
|
|
||||||
size := src.w * 4
|
|
||||||
parallel(0, src.h, func(ys <-chan int) {
|
|
||||||
for y := range ys {
|
|
||||||
i := y * dst.Stride
|
|
||||||
src.scan(0, y, src.w, y+1, dst.Pix[i:i+size])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return dst
|
|
||||||
}
|
|
463
vendor/github.com/disintegration/imaging/io.go
generated
vendored
Normal file
463
vendor/github.com/disintegration/imaging/io.go
generated
vendored
Normal file
@ -0,0 +1,463 @@
|
|||||||
|
package imaging
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"image"
|
||||||
|
"image/draw"
|
||||||
|
"image/gif"
|
||||||
|
"image/jpeg"
|
||||||
|
"image/png"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/image/bmp"
|
||||||
|
"golang.org/x/image/tiff"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Format is an image file format.
|
||||||
|
type Format int
|
||||||
|
|
||||||
|
// Image file formats.
|
||||||
|
const (
|
||||||
|
JPEG Format = iota
|
||||||
|
PNG
|
||||||
|
GIF
|
||||||
|
TIFF
|
||||||
|
BMP
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f Format) String() string {
|
||||||
|
switch f {
|
||||||
|
case JPEG:
|
||||||
|
return "JPEG"
|
||||||
|
case PNG:
|
||||||
|
return "PNG"
|
||||||
|
case GIF:
|
||||||
|
return "GIF"
|
||||||
|
case TIFF:
|
||||||
|
return "TIFF"
|
||||||
|
case BMP:
|
||||||
|
return "BMP"
|
||||||
|
default:
|
||||||
|
return "Unsupported"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var formatFromExt = map[string]Format{
|
||||||
|
"jpg": JPEG,
|
||||||
|
"jpeg": JPEG,
|
||||||
|
"png": PNG,
|
||||||
|
"tif": TIFF,
|
||||||
|
"tiff": TIFF,
|
||||||
|
"bmp": BMP,
|
||||||
|
"gif": GIF,
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatFromExtension parses image format from extension:
|
||||||
|
// "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
|
||||||
|
func FormatFromExtension(ext string) (Format, error) {
|
||||||
|
if f, ok := formatFromExt[strings.ToLower(strings.TrimPrefix(ext, "."))]; ok {
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
return -1, ErrUnsupportedFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatFromFilename parses image format from filename extension:
|
||||||
|
// "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
|
||||||
|
func FormatFromFilename(filename string) (Format, error) {
|
||||||
|
ext := filepath.Ext(filename)
|
||||||
|
return FormatFromExtension(ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrUnsupportedFormat means the given image format (or file extension) is unsupported.
|
||||||
|
ErrUnsupportedFormat = errors.New("imaging: unsupported image format")
|
||||||
|
)
|
||||||
|
|
||||||
|
type fileSystem interface {
|
||||||
|
Create(string) (io.WriteCloser, error)
|
||||||
|
Open(string) (io.ReadCloser, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type localFS struct{}
|
||||||
|
|
||||||
|
func (localFS) Create(name string) (io.WriteCloser, error) { return os.Create(name) }
|
||||||
|
func (localFS) Open(name string) (io.ReadCloser, error) { return os.Open(name) }
|
||||||
|
|
||||||
|
var fs fileSystem = localFS{}
|
||||||
|
|
||||||
|
type decodeConfig struct {
|
||||||
|
autoOrientation bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultDecodeConfig = decodeConfig{
|
||||||
|
autoOrientation: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeOption sets an optional parameter for the Decode and Open functions.
|
||||||
|
type DecodeOption func(*decodeConfig)
|
||||||
|
|
||||||
|
// AutoOrientation returns a DecodeOption that sets the auto-orientation mode.
|
||||||
|
// If auto-orientation is enabled, the image will be transformed after decoding
|
||||||
|
// according to the EXIF orientation tag (if present). By default it's disabled.
|
||||||
|
func AutoOrientation(enabled bool) DecodeOption {
|
||||||
|
return func(c *decodeConfig) {
|
||||||
|
c.autoOrientation = enabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode reads an image from r.
|
||||||
|
func Decode(r io.Reader, opts ...DecodeOption) (image.Image, error) {
|
||||||
|
cfg := defaultDecodeConfig
|
||||||
|
for _, option := range opts {
|
||||||
|
option(&cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !cfg.autoOrientation {
|
||||||
|
img, _, err := image.Decode(r)
|
||||||
|
return img, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var orient orientation
|
||||||
|
pr, pw := io.Pipe()
|
||||||
|
r = io.TeeReader(r, pw)
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
defer close(done)
|
||||||
|
orient = readOrientation(pr)
|
||||||
|
io.Copy(ioutil.Discard, pr)
|
||||||
|
}()
|
||||||
|
|
||||||
|
img, _, err := image.Decode(r)
|
||||||
|
pw.Close()
|
||||||
|
<-done
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fixOrientation(img, orient), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open loads an image from file.
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
//
|
||||||
|
// // Load an image from file.
|
||||||
|
// img, err := imaging.Open("test.jpg")
|
||||||
|
//
|
||||||
|
// // Load an image and transform it depending on the EXIF orientation tag (if present).
|
||||||
|
// img, err := imaging.Open("test.jpg", imaging.AutoOrientation(true))
|
||||||
|
//
|
||||||
|
func Open(filename string, opts ...DecodeOption) (image.Image, error) {
|
||||||
|
file, err := fs.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
return Decode(file, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
type encodeConfig struct {
|
||||||
|
jpegQuality int
|
||||||
|
gifNumColors int
|
||||||
|
gifQuantizer draw.Quantizer
|
||||||
|
gifDrawer draw.Drawer
|
||||||
|
pngCompressionLevel png.CompressionLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultEncodeConfig = encodeConfig{
|
||||||
|
jpegQuality: 95,
|
||||||
|
gifNumColors: 256,
|
||||||
|
gifQuantizer: nil,
|
||||||
|
gifDrawer: nil,
|
||||||
|
pngCompressionLevel: png.DefaultCompression,
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeOption sets an optional parameter for the Encode and Save functions.
|
||||||
|
type EncodeOption func(*encodeConfig)
|
||||||
|
|
||||||
|
// JPEGQuality returns an EncodeOption that sets the output JPEG quality.
|
||||||
|
// Quality ranges from 1 to 100 inclusive, higher is better. Default is 95.
|
||||||
|
func JPEGQuality(quality int) EncodeOption {
|
||||||
|
return func(c *encodeConfig) {
|
||||||
|
c.jpegQuality = quality
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GIFNumColors returns an EncodeOption that sets the maximum number of colors
|
||||||
|
// used in the GIF-encoded image. It ranges from 1 to 256. Default is 256.
|
||||||
|
func GIFNumColors(numColors int) EncodeOption {
|
||||||
|
return func(c *encodeConfig) {
|
||||||
|
c.gifNumColors = numColors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GIFQuantizer returns an EncodeOption that sets the quantizer that is used to produce
|
||||||
|
// a palette of the GIF-encoded image.
|
||||||
|
func GIFQuantizer(quantizer draw.Quantizer) EncodeOption {
|
||||||
|
return func(c *encodeConfig) {
|
||||||
|
c.gifQuantizer = quantizer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GIFDrawer returns an EncodeOption that sets the drawer that is used to convert
|
||||||
|
// the source image to the desired palette of the GIF-encoded image.
|
||||||
|
func GIFDrawer(drawer draw.Drawer) EncodeOption {
|
||||||
|
return func(c *encodeConfig) {
|
||||||
|
c.gifDrawer = drawer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PNGCompressionLevel returns an EncodeOption that sets the compression level
|
||||||
|
// of the PNG-encoded image. Default is png.DefaultCompression.
|
||||||
|
func PNGCompressionLevel(level png.CompressionLevel) EncodeOption {
|
||||||
|
return func(c *encodeConfig) {
|
||||||
|
c.pngCompressionLevel = level
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode writes the image img to w in the specified format (JPEG, PNG, GIF, TIFF or BMP).
|
||||||
|
func Encode(w io.Writer, img image.Image, format Format, opts ...EncodeOption) error {
|
||||||
|
cfg := defaultEncodeConfig
|
||||||
|
for _, option := range opts {
|
||||||
|
option(&cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
switch format {
|
||||||
|
case JPEG:
|
||||||
|
var rgba *image.RGBA
|
||||||
|
if nrgba, ok := img.(*image.NRGBA); ok {
|
||||||
|
if nrgba.Opaque() {
|
||||||
|
rgba = &image.RGBA{
|
||||||
|
Pix: nrgba.Pix,
|
||||||
|
Stride: nrgba.Stride,
|
||||||
|
Rect: nrgba.Rect,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if rgba != nil {
|
||||||
|
err = jpeg.Encode(w, rgba, &jpeg.Options{Quality: cfg.jpegQuality})
|
||||||
|
} else {
|
||||||
|
err = jpeg.Encode(w, img, &jpeg.Options{Quality: cfg.jpegQuality})
|
||||||
|
}
|
||||||
|
|
||||||
|
case PNG:
|
||||||
|
enc := png.Encoder{CompressionLevel: cfg.pngCompressionLevel}
|
||||||
|
err = enc.Encode(w, img)
|
||||||
|
|
||||||
|
case GIF:
|
||||||
|
err = gif.Encode(w, img, &gif.Options{
|
||||||
|
NumColors: cfg.gifNumColors,
|
||||||
|
Quantizer: cfg.gifQuantizer,
|
||||||
|
Drawer: cfg.gifDrawer,
|
||||||
|
})
|
||||||
|
|
||||||
|
case TIFF:
|
||||||
|
err = tiff.Encode(w, img, &tiff.Options{Compression: tiff.Deflate, Predictor: true})
|
||||||
|
|
||||||
|
case BMP:
|
||||||
|
err = bmp.Encode(w, img)
|
||||||
|
|
||||||
|
default:
|
||||||
|
err = ErrUnsupportedFormat
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save saves the image to file with the specified filename.
|
||||||
|
// The format is determined from the filename extension:
|
||||||
|
// "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
//
|
||||||
|
// // Save the image as PNG.
|
||||||
|
// err := imaging.Save(img, "out.png")
|
||||||
|
//
|
||||||
|
// // Save the image as JPEG with optional quality parameter set to 80.
|
||||||
|
// err := imaging.Save(img, "out.jpg", imaging.JPEGQuality(80))
|
||||||
|
//
|
||||||
|
func Save(img image.Image, filename string, opts ...EncodeOption) (err error) {
|
||||||
|
f, err := FormatFromFilename(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
file, err := fs.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
cerr := file.Close()
|
||||||
|
if err == nil {
|
||||||
|
err = cerr
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return Encode(file, img, f, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// orientation is an EXIF flag that specifies the transformation
|
||||||
|
// that should be applied to image to display it correctly.
|
||||||
|
type orientation int
|
||||||
|
|
||||||
|
const (
|
||||||
|
orientationUnspecified = 0
|
||||||
|
orientationNormal = 1
|
||||||
|
orientationFlipH = 2
|
||||||
|
orientationRotate180 = 3
|
||||||
|
orientationFlipV = 4
|
||||||
|
orientationTranspose = 5
|
||||||
|
orientationRotate270 = 6
|
||||||
|
orientationTransverse = 7
|
||||||
|
orientationRotate90 = 8
|
||||||
|
)
|
||||||
|
|
||||||
|
// readOrientation tries to read the orientation EXIF flag from image data in r.
|
||||||
|
// If the EXIF data block is not found or the orientation flag is not found
|
||||||
|
// or any other error occures while reading the data, it returns the
|
||||||
|
// orientationUnspecified (0) value.
|
||||||
|
func readOrientation(r io.Reader) orientation {
|
||||||
|
const (
|
||||||
|
markerSOI = 0xffd8
|
||||||
|
markerAPP1 = 0xffe1
|
||||||
|
exifHeader = 0x45786966
|
||||||
|
byteOrderBE = 0x4d4d
|
||||||
|
byteOrderLE = 0x4949
|
||||||
|
orientationTag = 0x0112
|
||||||
|
)
|
||||||
|
|
||||||
|
// Check if JPEG SOI marker is present.
|
||||||
|
var soi uint16
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &soi); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
if soi != markerSOI {
|
||||||
|
return orientationUnspecified // Missing JPEG SOI marker.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find JPEG APP1 marker.
|
||||||
|
for {
|
||||||
|
var marker, size uint16
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &marker); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &size); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
if marker>>8 != 0xff {
|
||||||
|
return orientationUnspecified // Invalid JPEG marker.
|
||||||
|
}
|
||||||
|
if marker == markerAPP1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if size < 2 {
|
||||||
|
return orientationUnspecified // Invalid block size.
|
||||||
|
}
|
||||||
|
if _, err := io.CopyN(ioutil.Discard, r, int64(size-2)); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if EXIF header is present.
|
||||||
|
var header uint32
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &header); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
if header != exifHeader {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
if _, err := io.CopyN(ioutil.Discard, r, 2); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read byte order information.
|
||||||
|
var (
|
||||||
|
byteOrderTag uint16
|
||||||
|
byteOrder binary.ByteOrder
|
||||||
|
)
|
||||||
|
if err := binary.Read(r, binary.BigEndian, &byteOrderTag); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
switch byteOrderTag {
|
||||||
|
case byteOrderBE:
|
||||||
|
byteOrder = binary.BigEndian
|
||||||
|
case byteOrderLE:
|
||||||
|
byteOrder = binary.LittleEndian
|
||||||
|
default:
|
||||||
|
return orientationUnspecified // Invalid byte order flag.
|
||||||
|
}
|
||||||
|
if _, err := io.CopyN(ioutil.Discard, r, 2); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the EXIF offset.
|
||||||
|
var offset uint32
|
||||||
|
if err := binary.Read(r, byteOrder, &offset); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
if offset < 8 {
|
||||||
|
return orientationUnspecified // Invalid offset value.
|
||||||
|
}
|
||||||
|
if _, err := io.CopyN(ioutil.Discard, r, int64(offset-8)); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the number of tags.
|
||||||
|
var numTags uint16
|
||||||
|
if err := binary.Read(r, byteOrder, &numTags); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the orientation tag.
|
||||||
|
for i := 0; i < int(numTags); i++ {
|
||||||
|
var tag uint16
|
||||||
|
if err := binary.Read(r, byteOrder, &tag); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
if tag != orientationTag {
|
||||||
|
if _, err := io.CopyN(ioutil.Discard, r, 10); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, err := io.CopyN(ioutil.Discard, r, 6); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
var val uint16
|
||||||
|
if err := binary.Read(r, byteOrder, &val); err != nil {
|
||||||
|
return orientationUnspecified
|
||||||
|
}
|
||||||
|
if val < 1 || val > 8 {
|
||||||
|
return orientationUnspecified // Invalid tag value.
|
||||||
|
}
|
||||||
|
return orientation(val)
|
||||||
|
}
|
||||||
|
return orientationUnspecified // Missing orientation tag.
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixOrientation applies a transform to img corresponding to the given orientation flag.
|
||||||
|
func fixOrientation(img image.Image, o orientation) image.Image {
|
||||||
|
switch o {
|
||||||
|
case orientationNormal:
|
||||||
|
case orientationFlipH:
|
||||||
|
img = FlipH(img)
|
||||||
|
case orientationFlipV:
|
||||||
|
img = FlipV(img)
|
||||||
|
case orientationRotate90:
|
||||||
|
img = Rotate90(img)
|
||||||
|
case orientationRotate180:
|
||||||
|
img = Rotate180(img)
|
||||||
|
case orientationRotate270:
|
||||||
|
img = Rotate270(img)
|
||||||
|
case orientationTranspose:
|
||||||
|
img = Transpose(img)
|
||||||
|
case orientationTransverse:
|
||||||
|
img = Transverse(img)
|
||||||
|
}
|
||||||
|
return img
|
||||||
|
}
|
34
vendor/github.com/disintegration/imaging/tools.go
generated
vendored
34
vendor/github.com/disintegration/imaging/tools.go
generated
vendored
@ -1,10 +1,44 @@
|
|||||||
package imaging
|
package imaging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// New creates a new image with the specified width and height, and fills it with the specified color.
|
||||||
|
func New(width, height int, fillColor color.Color) *image.NRGBA {
|
||||||
|
if width <= 0 || height <= 0 {
|
||||||
|
return &image.NRGBA{}
|
||||||
|
}
|
||||||
|
|
||||||
|
c := color.NRGBAModel.Convert(fillColor).(color.NRGBA)
|
||||||
|
if (c == color.NRGBA{0, 0, 0, 0}) {
|
||||||
|
return image.NewNRGBA(image.Rect(0, 0, width, height))
|
||||||
|
}
|
||||||
|
|
||||||
|
return &image.NRGBA{
|
||||||
|
Pix: bytes.Repeat([]byte{c.R, c.G, c.B, c.A}, width*height),
|
||||||
|
Stride: 4 * width,
|
||||||
|
Rect: image.Rect(0, 0, width, height),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns a copy of the given image.
|
||||||
|
func Clone(img image.Image) *image.NRGBA {
|
||||||
|
src := newScanner(img)
|
||||||
|
dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
|
||||||
|
size := src.w * 4
|
||||||
|
parallel(0, src.h, func(ys <-chan int) {
|
||||||
|
for y := range ys {
|
||||||
|
i := y * dst.Stride
|
||||||
|
src.scan(0, y, src.w, y+1, dst.Pix[i:i+size])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
// Anchor is the anchor point for image alignment.
|
// Anchor is the anchor point for image alignment.
|
||||||
type Anchor int
|
type Anchor int
|
||||||
|
|
||||||
|
33
vendor/github.com/lucasb-eyer/go-colorful/README.md
generated
vendored
33
vendor/github.com/lucasb-eyer/go-colorful/README.md
generated
vendored
@ -124,17 +124,16 @@ Because a `colorful.Color` implements Go's `color.Color` interface (found in the
|
|||||||
`image/color` package), it can be used anywhere that expects a `color.Color`.
|
`image/color` package), it can be used anywhere that expects a `color.Color`.
|
||||||
|
|
||||||
Furthermore, you can convert anything that implements the `color.Color` interface
|
Furthermore, you can convert anything that implements the `color.Color` interface
|
||||||
into a `colorful.Color` using the `MakeColorful` function:
|
into a `colorful.Color` using the `MakeColor` function:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
c := colorful.MakeColor(color.Gray16{12345})
|
c, ok := colorful.MakeColor(color.Gray16{12345})
|
||||||
```
|
```
|
||||||
|
|
||||||
**Caveat:** Be aware that for this latter conversion (using `MakeColor`) hits a corner-case
|
**Caveat:** Be aware that this latter conversion (using `MakeColor`) hits a
|
||||||
when alpha is exactly zero. Because `color.Color` uses pre-multiplied alpha colors,
|
corner-case when alpha is exactly zero. Because `color.Color` uses pre-multiplied
|
||||||
this means the RGB values are lost and it's impossible to recover them. The current
|
alpha colors, this means the RGB values are lost (set to 0) and it's impossible
|
||||||
implementation `panic()`s in that case, see [issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21)
|
to recover them. In such a case `MakeColor` will return `false` as its second value.
|
||||||
for discussion and suggesting alternatives.
|
|
||||||
|
|
||||||
### Comparing colors
|
### Comparing colors
|
||||||
In the RGB color space, the Euclidian distance between colors *doesn't* correspond
|
In the RGB color space, the Euclidian distance between colors *doesn't* correspond
|
||||||
@ -456,16 +455,26 @@ but that is outside the scope of this library.
|
|||||||
Thanks to [@ZirconiumX](https://github.com/ZirconiumX) for starting this investigation,
|
Thanks to [@ZirconiumX](https://github.com/ZirconiumX) for starting this investigation,
|
||||||
see [issue #18](https://github.com/lucasb-eyer/go-colorful/issues/18) for details.
|
see [issue #18](https://github.com/lucasb-eyer/go-colorful/issues/18) for details.
|
||||||
|
|
||||||
### Q: `MakeColor` panics when alpha is zero!
|
### Q: Why would `MakeColor` ever fail!?
|
||||||
A: Because in that case, the conversion is undefined. See
|
A: `MakeColor` fails when the alpha channel is zero. In that case, the
|
||||||
[issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21)
|
conversion is undefined. See [issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21)
|
||||||
as well as the short caveat discussion in the ["The `color.Color` interface"](README.md#the-colorcolor-interface) section above.
|
as well as the short caveat note in the ["The `color.Color` interface"](README.md#the-colorcolor-interface)
|
||||||
|
section above.
|
||||||
|
|
||||||
Who?
|
Who?
|
||||||
====
|
====
|
||||||
|
|
||||||
This library has been developed by Lucas Beyer with contributions from
|
This library has been developed by Lucas Beyer with contributions from
|
||||||
Bastien Dejean (@baskerville) and Phil Kulak (@pkulak).
|
Bastien Dejean (@baskerville), Phil Kulak (@pkulak) and Christian Muehlhaeuser (@muesli).
|
||||||
|
|
||||||
|
Release Notes
|
||||||
|
=============
|
||||||
|
|
||||||
|
### Version 1.0
|
||||||
|
- API Breaking change in `MakeColor`: instead of `panic`ing when alpha is zero, it now returns a secondary, boolean return value indicating success. See [the color.Color interface](https://github.com/lucasb-eyer/go-colorful#the-colorcolor-interface) section and [this FAQ entry](https://github.com/lucasb-eyer/go-colorful#q-why-would-makecolor-ever-fail) for details.
|
||||||
|
|
||||||
|
### Version 0.9
|
||||||
|
- Initial version number after having ignored versioning for a long time :)
|
||||||
|
|
||||||
License: MIT
|
License: MIT
|
||||||
============
|
============
|
||||||
|
7
vendor/github.com/lucasb-eyer/go-colorful/colors.go
generated
vendored
7
vendor/github.com/lucasb-eyer/go-colorful/colors.go
generated
vendored
@ -22,8 +22,11 @@ func (col Color) RGBA() (r, g, b, a uint32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Constructs a colorful.Color from something implementing color.Color
|
// Constructs a colorful.Color from something implementing color.Color
|
||||||
func MakeColor(col color.Color) Color {
|
func MakeColor(col color.Color) (Color, bool) {
|
||||||
r, g, b, a := col.RGBA()
|
r, g, b, a := col.RGBA()
|
||||||
|
if a == 0 {
|
||||||
|
return Color{0, 0, 0}, false
|
||||||
|
}
|
||||||
|
|
||||||
// Since color.Color is alpha pre-multiplied, we need to divide the
|
// Since color.Color is alpha pre-multiplied, we need to divide the
|
||||||
// RGB values by alpha again in order to get back the original RGB.
|
// RGB values by alpha again in order to get back the original RGB.
|
||||||
@ -34,7 +37,7 @@ func MakeColor(col color.Color) Color {
|
|||||||
b *= 0xffff
|
b *= 0xffff
|
||||||
b /= a
|
b /= a
|
||||||
|
|
||||||
return Color{float64(r) / 65535.0, float64(g) / 65535.0, float64(b) / 65535.0}
|
return Color{float64(r) / 65535.0, float64(g) / 65535.0, float64(b) / 65535.0}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Might come in handy sometimes to reduce boilerplate code.
|
// Might come in handy sometimes to reduce boilerplate code.
|
||||||
|
14
vendor/github.com/mattn/go-runewidth/runewidth.go
generated
vendored
14
vendor/github.com/mattn/go-runewidth/runewidth.go
generated
vendored
@ -1,13 +1,24 @@
|
|||||||
package runewidth
|
package runewidth
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// EastAsianWidth will be set true if the current locale is CJK
|
// EastAsianWidth will be set true if the current locale is CJK
|
||||||
EastAsianWidth = IsEastAsian()
|
EastAsianWidth bool
|
||||||
|
|
||||||
// DefaultCondition is a condition in current locale
|
// DefaultCondition is a condition in current locale
|
||||||
DefaultCondition = &Condition{EastAsianWidth}
|
DefaultCondition = &Condition{EastAsianWidth}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
env := os.Getenv("RUNEWIDTH_EASTASIAN")
|
||||||
|
if env == "" {
|
||||||
|
EastAsianWidth = IsEastAsian()
|
||||||
|
} else {
|
||||||
|
EastAsianWidth = env == "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type interval struct {
|
type interval struct {
|
||||||
first rune
|
first rune
|
||||||
last rune
|
last rune
|
||||||
@ -55,6 +66,7 @@ var private = table{
|
|||||||
var nonprint = table{
|
var nonprint = table{
|
||||||
{0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD},
|
{0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD},
|
||||||
{0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F},
|
{0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F},
|
||||||
|
{0x2028, 0x2029},
|
||||||
{0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF},
|
{0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF},
|
||||||
{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF},
|
{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF},
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/renstrom/fuzzysearch/LICENSE
generated
vendored
2
vendor/github.com/renstrom/fuzzysearch/LICENSE
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2015 Peter Renström
|
Copyright (c) 2018 Peter Lithammer
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
5
vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go
generated
vendored
5
vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go
generated
vendored
@ -112,10 +112,7 @@ Outer:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Count up remaining char
|
// Count up remaining char
|
||||||
for len(target) > 0 {
|
runeDiff += utf8.RuneCountInString(target)
|
||||||
target = target[utf8.RuneLen(rune(target[0])):]
|
|
||||||
runeDiff++
|
|
||||||
}
|
|
||||||
|
|
||||||
return runeDiff
|
return runeDiff
|
||||||
}
|
}
|
||||||
|
139
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
139
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
@ -13,6 +13,9 @@ import (
|
|||||||
|
|
||||||
// Conditionf uses a Comparison to assert a complex condition.
|
// Conditionf uses a Comparison to assert a complex condition.
|
||||||
func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool {
|
func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Condition(t, comp, append([]interface{}{msg}, args...)...)
|
return Condition(t, comp, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,11 +26,17 @@ func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bo
|
|||||||
// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
|
// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
|
||||||
// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
|
// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
|
||||||
func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Contains(t, s, contains, append([]interface{}{msg}, args...)...)
|
return Contains(t, s, contains, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||||
func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
|
func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return DirExists(t, path, append([]interface{}{msg}, args...)...)
|
return DirExists(t, path, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,6 +46,9 @@ func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
|
// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
|
||||||
func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
|
func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
|
return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +57,9 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string
|
|||||||
//
|
//
|
||||||
// assert.Emptyf(t, obj, "error message %s", "formatted")
|
// assert.Emptyf(t, obj, "error message %s", "formatted")
|
||||||
func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Empty(t, object, append([]interface{}{msg}, args...)...)
|
return Empty(t, object, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +71,9 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) boo
|
|||||||
// referenced values (as opposed to the memory addresses). Function equality
|
// referenced values (as opposed to the memory addresses). Function equality
|
||||||
// cannot be determined and will always fail.
|
// cannot be determined and will always fail.
|
||||||
func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Equal(t, expected, actual, append([]interface{}{msg}, args...)...)
|
return Equal(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +83,9 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar
|
|||||||
// actualObj, err := SomeFunction()
|
// actualObj, err := SomeFunction()
|
||||||
// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted")
|
// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted")
|
||||||
func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool {
|
func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...)
|
return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +94,9 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args
|
|||||||
//
|
//
|
||||||
// assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123))
|
// assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123))
|
||||||
func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
|
return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +107,9 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri
|
|||||||
// assert.Equal(t, expectedErrorf, err)
|
// assert.Equal(t, expectedErrorf, err)
|
||||||
// }
|
// }
|
||||||
func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Error(t, err, append([]interface{}{msg}, args...)...)
|
return Error(t, err, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,16 +117,25 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123))
|
// assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123))
|
||||||
func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Exactly(t, expected, actual, append([]interface{}{msg}, args...)...)
|
return Exactly(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Failf reports a failure through
|
// Failf reports a failure through
|
||||||
func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
|
func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Fail(t, failureMessage, append([]interface{}{msg}, args...)...)
|
return Fail(t, failureMessage, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FailNowf fails test
|
// FailNowf fails test
|
||||||
func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
|
func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return FailNow(t, failureMessage, append([]interface{}{msg}, args...)...)
|
return FailNow(t, failureMessage, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,31 +143,43 @@ func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}
|
|||||||
//
|
//
|
||||||
// assert.Falsef(t, myBool, "error message %s", "formatted")
|
// assert.Falsef(t, myBool, "error message %s", "formatted")
|
||||||
func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool {
|
func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return False(t, value, append([]interface{}{msg}, args...)...)
|
return False(t, value, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||||
func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
|
func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return FileExists(t, path, append([]interface{}{msg}, args...)...)
|
return FileExists(t, path, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPBodyContainsf asserts that a specified handler returns a
|
// HTTPBodyContainsf asserts that a specified handler returns a
|
||||||
// body that contains a string.
|
// body that contains a string.
|
||||||
//
|
//
|
||||||
// assert.HTTPBodyContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
|
return HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPBodyNotContainsf asserts that a specified handler returns a
|
// HTTPBodyNotContainsf asserts that a specified handler returns a
|
||||||
// body that does not contain a string.
|
// body that does not contain a string.
|
||||||
//
|
//
|
||||||
// assert.HTTPBodyNotContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
|
return HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,6 +189,9 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||||
func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
|
return HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,6 +201,9 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string,
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||||
func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
|
return HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +213,9 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
|
return HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +223,9 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin
|
|||||||
//
|
//
|
||||||
// assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
|
// assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
|
||||||
func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
|
func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)
|
return Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,31 +233,49 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms
|
|||||||
//
|
//
|
||||||
// assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
|
// assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
|
||||||
func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||||
func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InDeltaSlicef is the same as InDelta, except it compares two slices.
|
// InDeltaSlicef is the same as InDelta, except it compares two slices.
|
||||||
func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InEpsilonf asserts that expected and actual have a relative error less than epsilon
|
// InEpsilonf asserts that expected and actual have a relative error less than epsilon
|
||||||
func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
|
return InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
|
// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
|
||||||
func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
|
return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsTypef asserts that the specified objects are of the same type.
|
// IsTypef asserts that the specified objects are of the same type.
|
||||||
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return IsType(t, expectedType, object, append([]interface{}{msg}, args...)...)
|
return IsType(t, expectedType, object, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,6 +283,9 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin
|
|||||||
//
|
//
|
||||||
// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
|
// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
|
||||||
func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
|
func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...)
|
return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,6 +294,9 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int
|
|||||||
//
|
//
|
||||||
// assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
|
// assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
|
||||||
func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool {
|
func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Len(t, object, length, append([]interface{}{msg}, args...)...)
|
return Len(t, object, length, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +304,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf
|
|||||||
//
|
//
|
||||||
// assert.Nilf(t, err, "error message %s", "formatted")
|
// assert.Nilf(t, err, "error message %s", "formatted")
|
||||||
func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Nil(t, object, append([]interface{}{msg}, args...)...)
|
return Nil(t, object, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,6 +317,9 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool
|
|||||||
// assert.Equal(t, expectedObj, actualObj)
|
// assert.Equal(t, expectedObj, actualObj)
|
||||||
// }
|
// }
|
||||||
func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NoError(t, err, append([]interface{}{msg}, args...)...)
|
return NoError(t, err, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,6 +330,9 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
|||||||
// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
|
// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
|
||||||
// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
|
// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
|
||||||
func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotContains(t, s, contains, append([]interface{}{msg}, args...)...)
|
return NotContains(t, s, contains, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,6 +343,9 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a
|
|||||||
// assert.Equal(t, "two", obj[1])
|
// assert.Equal(t, "two", obj[1])
|
||||||
// }
|
// }
|
||||||
func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotEmpty(t, object, append([]interface{}{msg}, args...)...)
|
return NotEmpty(t, object, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,6 +356,9 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{})
|
|||||||
// Pointer variable equality is determined based on the equality of the
|
// Pointer variable equality is determined based on the equality of the
|
||||||
// referenced values (as opposed to the memory addresses).
|
// referenced values (as opposed to the memory addresses).
|
||||||
func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...)
|
return NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,6 +366,9 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string,
|
|||||||
//
|
//
|
||||||
// assert.NotNilf(t, err, "error message %s", "formatted")
|
// assert.NotNilf(t, err, "error message %s", "formatted")
|
||||||
func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotNil(t, object, append([]interface{}{msg}, args...)...)
|
return NotNil(t, object, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,6 +376,9 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bo
|
|||||||
//
|
//
|
||||||
// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted")
|
// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted")
|
||||||
func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
|
func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotPanics(t, f, append([]interface{}{msg}, args...)...)
|
return NotPanics(t, f, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,6 +387,9 @@ func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bo
|
|||||||
// assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
|
// assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
|
||||||
// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted")
|
// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted")
|
||||||
func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...)
|
return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,11 +398,17 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ..
|
|||||||
//
|
//
|
||||||
// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
|
// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
|
||||||
func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotSubset(t, list, subset, append([]interface{}{msg}, args...)...)
|
return NotSubset(t, list, subset, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotZerof asserts that i is not the zero value for its type.
|
// NotZerof asserts that i is not the zero value for its type.
|
||||||
func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
|
func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotZero(t, i, append([]interface{}{msg}, args...)...)
|
return NotZero(t, i, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,6 +416,9 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted")
|
// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted")
|
||||||
func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
|
func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Panics(t, f, append([]interface{}{msg}, args...)...)
|
return Panics(t, f, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,6 +427,9 @@ func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool
|
|||||||
//
|
//
|
||||||
// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
||||||
func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
|
func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...)
|
return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,6 +438,9 @@ func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg str
|
|||||||
// assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
|
// assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
|
||||||
// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted")
|
// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted")
|
||||||
func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Regexp(t, rx, str, append([]interface{}{msg}, args...)...)
|
return Regexp(t, rx, str, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,6 +449,9 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in
|
|||||||
//
|
//
|
||||||
// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
|
// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
|
||||||
func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Subset(t, list, subset, append([]interface{}{msg}, args...)...)
|
return Subset(t, list, subset, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,6 +459,9 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args
|
|||||||
//
|
//
|
||||||
// assert.Truef(t, myBool, "error message %s", "formatted")
|
// assert.Truef(t, myBool, "error message %s", "formatted")
|
||||||
func Truef(t TestingT, value bool, msg string, args ...interface{}) bool {
|
func Truef(t TestingT, value bool, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return True(t, value, append([]interface{}{msg}, args...)...)
|
return True(t, value, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,10 +469,16 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
|
// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
|
||||||
func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
|
func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zerof asserts that i is the zero value for its type.
|
// Zerof asserts that i is the zero value for its type.
|
||||||
func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
|
func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Zero(t, i, append([]interface{}{msg}, args...)...)
|
return Zero(t, i, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
1
vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
generated
vendored
1
vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
generated
vendored
@ -1,4 +1,5 @@
|
|||||||
{{.CommentFormat}}
|
{{.CommentFormat}}
|
||||||
func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool {
|
func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok { h.Helper() }
|
||||||
return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}})
|
return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}})
|
||||||
}
|
}
|
||||||
|
278
vendor/github.com/stretchr/testify/assert/assertion_forward.go
generated
vendored
278
vendor/github.com/stretchr/testify/assert/assertion_forward.go
generated
vendored
@ -13,11 +13,17 @@ import (
|
|||||||
|
|
||||||
// Condition uses a Comparison to assert a complex condition.
|
// Condition uses a Comparison to assert a complex condition.
|
||||||
func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Condition(a.t, comp, msgAndArgs...)
|
return Condition(a.t, comp, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conditionf uses a Comparison to assert a complex condition.
|
// Conditionf uses a Comparison to assert a complex condition.
|
||||||
func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool {
|
func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Conditionf(a.t, comp, msg, args...)
|
return Conditionf(a.t, comp, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,6 +34,9 @@ func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}
|
|||||||
// a.Contains(["Hello", "World"], "World")
|
// a.Contains(["Hello", "World"], "World")
|
||||||
// a.Contains({"Hello": "World"}, "Hello")
|
// a.Contains({"Hello": "World"}, "Hello")
|
||||||
func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Contains(a.t, s, contains, msgAndArgs...)
|
return Contains(a.t, s, contains, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,16 +47,25 @@ func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ..
|
|||||||
// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted")
|
// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted")
|
||||||
// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted")
|
// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted")
|
||||||
func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Containsf(a.t, s, contains, msg, args...)
|
return Containsf(a.t, s, contains, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||||
func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return DirExists(a.t, path, msgAndArgs...)
|
return DirExists(a.t, path, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
// DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||||
func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool {
|
func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return DirExistsf(a.t, path, msg, args...)
|
return DirExistsf(a.t, path, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +75,9 @@ func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bo
|
|||||||
//
|
//
|
||||||
// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2])
|
// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2])
|
||||||
func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return ElementsMatch(a.t, listA, listB, msgAndArgs...)
|
return ElementsMatch(a.t, listA, listB, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +87,9 @@ func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndA
|
|||||||
//
|
//
|
||||||
// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
|
// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
|
||||||
func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return ElementsMatchf(a.t, listA, listB, msg, args...)
|
return ElementsMatchf(a.t, listA, listB, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +98,9 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st
|
|||||||
//
|
//
|
||||||
// a.Empty(obj)
|
// a.Empty(obj)
|
||||||
func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Empty(a.t, object, msgAndArgs...)
|
return Empty(a.t, object, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +109,9 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// a.Emptyf(obj, "error message %s", "formatted")
|
// a.Emptyf(obj, "error message %s", "formatted")
|
||||||
func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Emptyf(a.t, object, msg, args...)
|
return Emptyf(a.t, object, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +123,9 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{})
|
|||||||
// referenced values (as opposed to the memory addresses). Function equality
|
// referenced values (as opposed to the memory addresses). Function equality
|
||||||
// cannot be determined and will always fail.
|
// cannot be determined and will always fail.
|
||||||
func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Equal(a.t, expected, actual, msgAndArgs...)
|
return Equal(a.t, expected, actual, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +135,9 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs
|
|||||||
// actualObj, err := SomeFunction()
|
// actualObj, err := SomeFunction()
|
||||||
// a.EqualError(err, expectedErrorString)
|
// a.EqualError(err, expectedErrorString)
|
||||||
func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return EqualError(a.t, theError, errString, msgAndArgs...)
|
return EqualError(a.t, theError, errString, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +147,9 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...
|
|||||||
// actualObj, err := SomeFunction()
|
// actualObj, err := SomeFunction()
|
||||||
// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted")
|
// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted")
|
||||||
func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool {
|
func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return EqualErrorf(a.t, theError, errString, msg, args...)
|
return EqualErrorf(a.t, theError, errString, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +158,9 @@ func (a *Assertions) EqualErrorf(theError error, errString string, msg string, a
|
|||||||
//
|
//
|
||||||
// a.EqualValues(uint32(123), int32(123))
|
// a.EqualValues(uint32(123), int32(123))
|
||||||
func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return EqualValues(a.t, expected, actual, msgAndArgs...)
|
return EqualValues(a.t, expected, actual, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,6 +169,9 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn
|
|||||||
//
|
//
|
||||||
// a.EqualValuesf(uint32(123, "error message %s", "formatted"), int32(123))
|
// a.EqualValuesf(uint32(123, "error message %s", "formatted"), int32(123))
|
||||||
func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return EqualValuesf(a.t, expected, actual, msg, args...)
|
return EqualValuesf(a.t, expected, actual, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +183,9 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg
|
|||||||
// referenced values (as opposed to the memory addresses). Function equality
|
// referenced values (as opposed to the memory addresses). Function equality
|
||||||
// cannot be determined and will always fail.
|
// cannot be determined and will always fail.
|
||||||
func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Equalf(a.t, expected, actual, msg, args...)
|
return Equalf(a.t, expected, actual, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,6 +196,9 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string
|
|||||||
// assert.Equal(t, expectedError, err)
|
// assert.Equal(t, expectedError, err)
|
||||||
// }
|
// }
|
||||||
func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Error(a.t, err, msgAndArgs...)
|
return Error(a.t, err, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,6 +209,9 @@ func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
|
|||||||
// assert.Equal(t, expectedErrorf, err)
|
// assert.Equal(t, expectedErrorf, err)
|
||||||
// }
|
// }
|
||||||
func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
|
func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Errorf(a.t, err, msg, args...)
|
return Errorf(a.t, err, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +219,9 @@ func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// a.Exactly(int32(123), int64(123))
|
// a.Exactly(int32(123), int64(123))
|
||||||
func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Exactly(a.t, expected, actual, msgAndArgs...)
|
return Exactly(a.t, expected, actual, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,26 +229,41 @@ func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArg
|
|||||||
//
|
//
|
||||||
// a.Exactlyf(int32(123, "error message %s", "formatted"), int64(123))
|
// a.Exactlyf(int32(123, "error message %s", "formatted"), int64(123))
|
||||||
func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Exactlyf(a.t, expected, actual, msg, args...)
|
return Exactlyf(a.t, expected, actual, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail reports a failure through
|
// Fail reports a failure through
|
||||||
func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Fail(a.t, failureMessage, msgAndArgs...)
|
return Fail(a.t, failureMessage, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FailNow fails test
|
// FailNow fails test
|
||||||
func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return FailNow(a.t, failureMessage, msgAndArgs...)
|
return FailNow(a.t, failureMessage, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FailNowf fails test
|
// FailNowf fails test
|
||||||
func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool {
|
func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return FailNowf(a.t, failureMessage, msg, args...)
|
return FailNowf(a.t, failureMessage, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Failf reports a failure through
|
// Failf reports a failure through
|
||||||
func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool {
|
func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Failf(a.t, failureMessage, msg, args...)
|
return Failf(a.t, failureMessage, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,6 +271,9 @@ func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{
|
|||||||
//
|
//
|
||||||
// a.False(myBool)
|
// a.False(myBool)
|
||||||
func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return False(a.t, value, msgAndArgs...)
|
return False(a.t, value, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,56 +281,77 @@ func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// a.Falsef(myBool, "error message %s", "formatted")
|
// a.Falsef(myBool, "error message %s", "formatted")
|
||||||
func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool {
|
func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Falsef(a.t, value, msg, args...)
|
return Falsef(a.t, value, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||||
func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return FileExists(a.t, path, msgAndArgs...)
|
return FileExists(a.t, path, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
// FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||||
func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool {
|
func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return FileExistsf(a.t, path, msg, args...)
|
return FileExistsf(a.t, path, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPBodyContains asserts that a specified handler returns a
|
// HTTPBodyContains asserts that a specified handler returns a
|
||||||
// body that contains a string.
|
// body that contains a string.
|
||||||
//
|
//
|
||||||
// a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)
|
return HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPBodyContainsf asserts that a specified handler returns a
|
// HTTPBodyContainsf asserts that a specified handler returns a
|
||||||
// body that contains a string.
|
// body that contains a string.
|
||||||
//
|
//
|
||||||
// a.HTTPBodyContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)
|
return HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPBodyNotContains asserts that a specified handler returns a
|
// HTTPBodyNotContains asserts that a specified handler returns a
|
||||||
// body that does not contain a string.
|
// body that does not contain a string.
|
||||||
//
|
//
|
||||||
// a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)
|
return HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPBodyNotContainsf asserts that a specified handler returns a
|
// HTTPBodyNotContainsf asserts that a specified handler returns a
|
||||||
// body that does not contain a string.
|
// body that does not contain a string.
|
||||||
//
|
//
|
||||||
// a.HTTPBodyNotContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)
|
return HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,6 +361,9 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPError(a.t, handler, method, url, values, msgAndArgs...)
|
return HTTPError(a.t, handler, method, url, values, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,6 +373,9 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||||
func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPErrorf(a.t, handler, method, url, values, msg, args...)
|
return HTTPErrorf(a.t, handler, method, url, values, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,6 +385,9 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)
|
return HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,6 +397,9 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
// Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
|
||||||
func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPRedirectf(a.t, handler, method, url, values, msg, args...)
|
return HTTPRedirectf(a.t, handler, method, url, values, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,6 +409,9 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)
|
return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,6 +421,9 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return HTTPSuccessf(a.t, handler, method, url, values, msg, args...)
|
return HTTPSuccessf(a.t, handler, method, url, values, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,6 +431,9 @@ func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url s
|
|||||||
//
|
//
|
||||||
// a.Implements((*MyInterface)(nil), new(MyObject))
|
// a.Implements((*MyInterface)(nil), new(MyObject))
|
||||||
func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Implements(a.t, interfaceObject, object, msgAndArgs...)
|
return Implements(a.t, interfaceObject, object, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,6 +441,9 @@ func (a *Assertions) Implements(interfaceObject interface{}, object interface{},
|
|||||||
//
|
//
|
||||||
// a.Implementsf((*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
|
// a.Implementsf((*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
|
||||||
func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Implementsf(a.t, interfaceObject, object, msg, args...)
|
return Implementsf(a.t, interfaceObject, object, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,26 +451,41 @@ func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}
|
|||||||
//
|
//
|
||||||
// a.InDelta(math.Pi, (22 / 7.0), 0.01)
|
// a.InDelta(math.Pi, (22 / 7.0), 0.01)
|
||||||
func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InDelta(a.t, expected, actual, delta, msgAndArgs...)
|
return InDelta(a.t, expected, actual, delta, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||||
func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)
|
return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||||
func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)
|
return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InDeltaSlice is the same as InDelta, except it compares two slices.
|
// InDeltaSlice is the same as InDelta, except it compares two slices.
|
||||||
func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
|
return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InDeltaSlicef is the same as InDelta, except it compares two slices.
|
// InDeltaSlicef is the same as InDelta, except it compares two slices.
|
||||||
func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InDeltaSlicef(a.t, expected, actual, delta, msg, args...)
|
return InDeltaSlicef(a.t, expected, actual, delta, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,36 +493,57 @@ func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, del
|
|||||||
//
|
//
|
||||||
// a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
|
// a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
|
||||||
func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InDeltaf(a.t, expected, actual, delta, msg, args...)
|
return InDeltaf(a.t, expected, actual, delta, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InEpsilon asserts that expected and actual have a relative error less than epsilon
|
// InEpsilon asserts that expected and actual have a relative error less than epsilon
|
||||||
func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
|
return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
|
// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
|
||||||
func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)
|
return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
|
// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
|
||||||
func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)
|
return InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InEpsilonf asserts that expected and actual have a relative error less than epsilon
|
// InEpsilonf asserts that expected and actual have a relative error less than epsilon
|
||||||
func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
|
return InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsType asserts that the specified objects are of the same type.
|
// IsType asserts that the specified objects are of the same type.
|
||||||
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return IsType(a.t, expectedType, object, msgAndArgs...)
|
return IsType(a.t, expectedType, object, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsTypef asserts that the specified objects are of the same type.
|
// IsTypef asserts that the specified objects are of the same type.
|
||||||
func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return IsTypef(a.t, expectedType, object, msg, args...)
|
return IsTypef(a.t, expectedType, object, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,6 +551,9 @@ func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg s
|
|||||||
//
|
//
|
||||||
// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||||
func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return JSONEq(a.t, expected, actual, msgAndArgs...)
|
return JSONEq(a.t, expected, actual, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,6 +561,9 @@ func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interf
|
|||||||
//
|
//
|
||||||
// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
|
// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
|
||||||
func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool {
|
func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return JSONEqf(a.t, expected, actual, msg, args...)
|
return JSONEqf(a.t, expected, actual, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,6 +572,9 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ..
|
|||||||
//
|
//
|
||||||
// a.Len(mySlice, 3)
|
// a.Len(mySlice, 3)
|
||||||
func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Len(a.t, object, length, msgAndArgs...)
|
return Len(a.t, object, length, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,6 +583,9 @@ func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface
|
|||||||
//
|
//
|
||||||
// a.Lenf(mySlice, 3, "error message %s", "formatted")
|
// a.Lenf(mySlice, 3, "error message %s", "formatted")
|
||||||
func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool {
|
func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Lenf(a.t, object, length, msg, args...)
|
return Lenf(a.t, object, length, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,6 +593,9 @@ func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...in
|
|||||||
//
|
//
|
||||||
// a.Nil(err)
|
// a.Nil(err)
|
||||||
func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Nil(a.t, object, msgAndArgs...)
|
return Nil(a.t, object, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,6 +603,9 @@ func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// a.Nilf(err, "error message %s", "formatted")
|
// a.Nilf(err, "error message %s", "formatted")
|
||||||
func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Nilf(a.t, object, msg, args...)
|
return Nilf(a.t, object, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,6 +616,9 @@ func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) b
|
|||||||
// assert.Equal(t, expectedObj, actualObj)
|
// assert.Equal(t, expectedObj, actualObj)
|
||||||
// }
|
// }
|
||||||
func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NoError(a.t, err, msgAndArgs...)
|
return NoError(a.t, err, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,6 +629,9 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {
|
|||||||
// assert.Equal(t, expectedObj, actualObj)
|
// assert.Equal(t, expectedObj, actualObj)
|
||||||
// }
|
// }
|
||||||
func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {
|
func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NoErrorf(a.t, err, msg, args...)
|
return NoErrorf(a.t, err, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,6 +642,9 @@ func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {
|
|||||||
// a.NotContains(["Hello", "World"], "Earth")
|
// a.NotContains(["Hello", "World"], "Earth")
|
||||||
// a.NotContains({"Hello": "World"}, "Earth")
|
// a.NotContains({"Hello": "World"}, "Earth")
|
||||||
func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotContains(a.t, s, contains, msgAndArgs...)
|
return NotContains(a.t, s, contains, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,6 +655,9 @@ func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs
|
|||||||
// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted")
|
// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted")
|
||||||
// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted")
|
// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted")
|
||||||
func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotContainsf(a.t, s, contains, msg, args...)
|
return NotContainsf(a.t, s, contains, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,6 +668,9 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin
|
|||||||
// assert.Equal(t, "two", obj[1])
|
// assert.Equal(t, "two", obj[1])
|
||||||
// }
|
// }
|
||||||
func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotEmpty(a.t, object, msgAndArgs...)
|
return NotEmpty(a.t, object, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,6 +681,9 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) boo
|
|||||||
// assert.Equal(t, "two", obj[1])
|
// assert.Equal(t, "two", obj[1])
|
||||||
// }
|
// }
|
||||||
func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotEmptyf(a.t, object, msg, args...)
|
return NotEmptyf(a.t, object, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,6 +694,9 @@ func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface
|
|||||||
// Pointer variable equality is determined based on the equality of the
|
// Pointer variable equality is determined based on the equality of the
|
||||||
// referenced values (as opposed to the memory addresses).
|
// referenced values (as opposed to the memory addresses).
|
||||||
func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotEqual(a.t, expected, actual, msgAndArgs...)
|
return NotEqual(a.t, expected, actual, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,6 +707,9 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr
|
|||||||
// Pointer variable equality is determined based on the equality of the
|
// Pointer variable equality is determined based on the equality of the
|
||||||
// referenced values (as opposed to the memory addresses).
|
// referenced values (as opposed to the memory addresses).
|
||||||
func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotEqualf(a.t, expected, actual, msg, args...)
|
return NotEqualf(a.t, expected, actual, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,6 +717,9 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str
|
|||||||
//
|
//
|
||||||
// a.NotNil(err)
|
// a.NotNil(err)
|
||||||
func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotNil(a.t, object, msgAndArgs...)
|
return NotNil(a.t, object, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,6 +727,9 @@ func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool
|
|||||||
//
|
//
|
||||||
// a.NotNilf(err, "error message %s", "formatted")
|
// a.NotNilf(err, "error message %s", "formatted")
|
||||||
func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotNilf(a.t, object, msg, args...)
|
return NotNilf(a.t, object, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,6 +737,9 @@ func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}
|
|||||||
//
|
//
|
||||||
// a.NotPanics(func(){ RemainCalm() })
|
// a.NotPanics(func(){ RemainCalm() })
|
||||||
func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotPanics(a.t, f, msgAndArgs...)
|
return NotPanics(a.t, f, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,6 +747,9 @@ func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool
|
|||||||
//
|
//
|
||||||
// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted")
|
// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted")
|
||||||
func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
|
func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotPanicsf(a.t, f, msg, args...)
|
return NotPanicsf(a.t, f, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,6 +758,9 @@ func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}
|
|||||||
// a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
|
// a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
|
||||||
// a.NotRegexp("^start", "it's not starting")
|
// a.NotRegexp("^start", "it's not starting")
|
||||||
func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotRegexp(a.t, rx, str, msgAndArgs...)
|
return NotRegexp(a.t, rx, str, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,6 +769,9 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in
|
|||||||
// a.NotRegexpf(regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
|
// a.NotRegexpf(regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
|
||||||
// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted")
|
// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted")
|
||||||
func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotRegexpf(a.t, rx, str, msg, args...)
|
return NotRegexpf(a.t, rx, str, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,6 +780,9 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg
|
|||||||
//
|
//
|
||||||
// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
|
// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
|
||||||
func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotSubset(a.t, list, subset, msgAndArgs...)
|
return NotSubset(a.t, list, subset, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,16 +791,25 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
|
|||||||
//
|
//
|
||||||
// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
|
// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
|
||||||
func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotSubsetf(a.t, list, subset, msg, args...)
|
return NotSubsetf(a.t, list, subset, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotZero asserts that i is not the zero value for its type.
|
// NotZero asserts that i is not the zero value for its type.
|
||||||
func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotZero(a.t, i, msgAndArgs...)
|
return NotZero(a.t, i, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotZerof asserts that i is not the zero value for its type.
|
// NotZerof asserts that i is not the zero value for its type.
|
||||||
func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return NotZerof(a.t, i, msg, args...)
|
return NotZerof(a.t, i, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,6 +817,9 @@ func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bo
|
|||||||
//
|
//
|
||||||
// a.Panics(func(){ GoCrazy() })
|
// a.Panics(func(){ GoCrazy() })
|
||||||
func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Panics(a.t, f, msgAndArgs...)
|
return Panics(a.t, f, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,6 +828,9 @@ func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// a.PanicsWithValue("crazy error", func(){ GoCrazy() })
|
// a.PanicsWithValue("crazy error", func(){ GoCrazy() })
|
||||||
func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return PanicsWithValue(a.t, expected, f, msgAndArgs...)
|
return PanicsWithValue(a.t, expected, f, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,6 +839,9 @@ func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgA
|
|||||||
//
|
//
|
||||||
// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
||||||
func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
|
func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return PanicsWithValuef(a.t, expected, f, msg, args...)
|
return PanicsWithValuef(a.t, expected, f, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,6 +849,9 @@ func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg
|
|||||||
//
|
//
|
||||||
// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted")
|
// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted")
|
||||||
func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
|
func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Panicsf(a.t, f, msg, args...)
|
return Panicsf(a.t, f, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,6 +860,9 @@ func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) b
|
|||||||
// a.Regexp(regexp.MustCompile("start"), "it's starting")
|
// a.Regexp(regexp.MustCompile("start"), "it's starting")
|
||||||
// a.Regexp("start...$", "it's not starting")
|
// a.Regexp("start...$", "it's not starting")
|
||||||
func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Regexp(a.t, rx, str, msgAndArgs...)
|
return Regexp(a.t, rx, str, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,6 +871,9 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter
|
|||||||
// a.Regexpf(regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
|
// a.Regexpf(regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
|
||||||
// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted")
|
// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted")
|
||||||
func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Regexpf(a.t, rx, str, msg, args...)
|
return Regexpf(a.t, rx, str, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,6 +882,9 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args .
|
|||||||
//
|
//
|
||||||
// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
|
// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
|
||||||
func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Subset(a.t, list, subset, msgAndArgs...)
|
return Subset(a.t, list, subset, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -644,6 +893,9 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
|
|||||||
//
|
//
|
||||||
// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
|
// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
|
||||||
func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Subsetf(a.t, list, subset, msg, args...)
|
return Subsetf(a.t, list, subset, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,6 +903,9 @@ func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, a
|
|||||||
//
|
//
|
||||||
// a.True(myBool)
|
// a.True(myBool)
|
||||||
func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return True(a.t, value, msgAndArgs...)
|
return True(a.t, value, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,6 +913,9 @@ func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// a.Truef(myBool, "error message %s", "formatted")
|
// a.Truef(myBool, "error message %s", "formatted")
|
||||||
func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool {
|
func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Truef(a.t, value, msg, args...)
|
return Truef(a.t, value, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,6 +923,9 @@ func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// a.WithinDuration(time.Now(), time.Now(), 10*time.Second)
|
// a.WithinDuration(time.Now(), time.Now(), 10*time.Second)
|
||||||
func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
|
return WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,15 +933,24 @@ func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta
|
|||||||
//
|
//
|
||||||
// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
|
// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
|
||||||
func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
|
func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return WithinDurationf(a.t, expected, actual, delta, msg, args...)
|
return WithinDurationf(a.t, expected, actual, delta, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zero asserts that i is the zero value for its type.
|
// Zero asserts that i is the zero value for its type.
|
||||||
func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Zero(a.t, i, msgAndArgs...)
|
return Zero(a.t, i, msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zerof asserts that i is the zero value for its type.
|
// Zerof asserts that i is the zero value for its type.
|
||||||
func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool {
|
func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
return Zerof(a.t, i, msg, args...)
|
return Zerof(a.t, i, msg, args...)
|
||||||
}
|
}
|
||||||
|
1
vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
generated
vendored
1
vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
generated
vendored
@ -1,4 +1,5 @@
|
|||||||
{{.CommentWithoutT "a"}}
|
{{.CommentWithoutT "a"}}
|
||||||
func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool {
|
func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok { h.Helper() }
|
||||||
return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
|
return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
|
||||||
}
|
}
|
||||||
|
216
vendor/github.com/stretchr/testify/assert/assertions.go
generated
vendored
216
vendor/github.com/stretchr/testify/assert/assertions.go
generated
vendored
@ -27,6 +27,22 @@ type TestingT interface {
|
|||||||
Errorf(format string, args ...interface{})
|
Errorf(format string, args ...interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful
|
||||||
|
// for table driven tests.
|
||||||
|
type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool
|
||||||
|
|
||||||
|
// ValueAssertionFunc is a common function prototype when validating a single value. Can be useful
|
||||||
|
// for table driven tests.
|
||||||
|
type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool
|
||||||
|
|
||||||
|
// BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful
|
||||||
|
// for table driven tests.
|
||||||
|
type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool
|
||||||
|
|
||||||
|
// ValuesAssertionFunc is a common function prototype when validating an error value. Can be useful
|
||||||
|
// for table driven tests.
|
||||||
|
type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool
|
||||||
|
|
||||||
// Comparison a custom function that returns true on success and false on failure
|
// Comparison a custom function that returns true on success and false on failure
|
||||||
type Comparison func() (success bool)
|
type Comparison func() (success bool)
|
||||||
|
|
||||||
@ -38,21 +54,23 @@ type Comparison func() (success bool)
|
|||||||
//
|
//
|
||||||
// This function does no assertion of any kind.
|
// This function does no assertion of any kind.
|
||||||
func ObjectsAreEqual(expected, actual interface{}) bool {
|
func ObjectsAreEqual(expected, actual interface{}) bool {
|
||||||
|
|
||||||
if expected == nil || actual == nil {
|
if expected == nil || actual == nil {
|
||||||
return expected == actual
|
return expected == actual
|
||||||
}
|
}
|
||||||
if exp, ok := expected.([]byte); ok {
|
|
||||||
act, ok := actual.([]byte)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
} else if exp == nil || act == nil {
|
|
||||||
return exp == nil && act == nil
|
|
||||||
}
|
|
||||||
return bytes.Equal(exp, act)
|
|
||||||
}
|
|
||||||
return reflect.DeepEqual(expected, actual)
|
|
||||||
|
|
||||||
|
exp, ok := expected.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return reflect.DeepEqual(expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
act, ok := actual.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if exp == nil || act == nil {
|
||||||
|
return exp == nil && act == nil
|
||||||
|
}
|
||||||
|
return bytes.Equal(exp, act)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectsAreEqualValues gets whether two objects are equal, or if their
|
// ObjectsAreEqualValues gets whether two objects are equal, or if their
|
||||||
@ -156,21 +174,6 @@ func isTest(name, prefix string) bool {
|
|||||||
return !unicode.IsLower(rune)
|
return !unicode.IsLower(rune)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getWhitespaceString returns a string that is long enough to overwrite the default
|
|
||||||
// output from the go testing framework.
|
|
||||||
func getWhitespaceString() string {
|
|
||||||
|
|
||||||
_, file, line, ok := runtime.Caller(1)
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
parts := strings.Split(file, "/")
|
|
||||||
file = parts[len(parts)-1]
|
|
||||||
|
|
||||||
return strings.Repeat(" ", len(fmt.Sprintf("%s:%d: ", file, line)))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
|
func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
|
||||||
if len(msgAndArgs) == 0 || msgAndArgs == nil {
|
if len(msgAndArgs) == 0 || msgAndArgs == nil {
|
||||||
return ""
|
return ""
|
||||||
@ -195,7 +198,7 @@ func indentMessageLines(message string, longestLabelLen int) string {
|
|||||||
// no need to align first line because it starts at the correct location (after the label)
|
// no need to align first line because it starts at the correct location (after the label)
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
// append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab
|
// append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab
|
||||||
outBuf.WriteString("\n\r\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
|
outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
|
||||||
}
|
}
|
||||||
outBuf.WriteString(scanner.Text())
|
outBuf.WriteString(scanner.Text())
|
||||||
}
|
}
|
||||||
@ -209,6 +212,9 @@ type failNower interface {
|
|||||||
|
|
||||||
// FailNow fails test
|
// FailNow fails test
|
||||||
func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
|
func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
Fail(t, failureMessage, msgAndArgs...)
|
Fail(t, failureMessage, msgAndArgs...)
|
||||||
|
|
||||||
// We cannot extend TestingT with FailNow() and
|
// We cannot extend TestingT with FailNow() and
|
||||||
@ -227,8 +233,11 @@ func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool
|
|||||||
|
|
||||||
// Fail reports a failure through
|
// Fail reports a failure through
|
||||||
func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
|
func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
content := []labeledContent{
|
content := []labeledContent{
|
||||||
{"Error Trace", strings.Join(CallerInfo(), "\n\r\t\t\t")},
|
{"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")},
|
||||||
{"Error", failureMessage},
|
{"Error", failureMessage},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +253,7 @@ func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
|
|||||||
content = append(content, labeledContent{"Messages", message})
|
content = append(content, labeledContent{"Messages", message})
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Errorf("%s", "\r"+getWhitespaceString()+labeledOutput(content...))
|
t.Errorf("\n%s", ""+labeledOutput(content...))
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -256,7 +265,7 @@ type labeledContent struct {
|
|||||||
|
|
||||||
// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner:
|
// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner:
|
||||||
//
|
//
|
||||||
// \r\t{{label}}:{{align_spaces}}\t{{content}}\n
|
// \t{{label}}:{{align_spaces}}\t{{content}}\n
|
||||||
//
|
//
|
||||||
// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label.
|
// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label.
|
||||||
// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this
|
// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this
|
||||||
@ -272,7 +281,7 @@ func labeledOutput(content ...labeledContent) string {
|
|||||||
}
|
}
|
||||||
var output string
|
var output string
|
||||||
for _, v := range content {
|
for _, v := range content {
|
||||||
output += "\r\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
|
output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
|
||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
@ -281,6 +290,9 @@ func labeledOutput(content ...labeledContent) string {
|
|||||||
//
|
//
|
||||||
// assert.Implements(t, (*MyInterface)(nil), new(MyObject))
|
// assert.Implements(t, (*MyInterface)(nil), new(MyObject))
|
||||||
func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
interfaceType := reflect.TypeOf(interfaceObject).Elem()
|
interfaceType := reflect.TypeOf(interfaceObject).Elem()
|
||||||
|
|
||||||
if object == nil {
|
if object == nil {
|
||||||
@ -295,6 +307,9 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg
|
|||||||
|
|
||||||
// IsType asserts that the specified objects are of the same type.
|
// IsType asserts that the specified objects are of the same type.
|
||||||
func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
|
if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
|
||||||
return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
|
return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
|
||||||
@ -311,6 +326,9 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs
|
|||||||
// referenced values (as opposed to the memory addresses). Function equality
|
// referenced values (as opposed to the memory addresses). Function equality
|
||||||
// cannot be determined and will always fail.
|
// cannot be determined and will always fail.
|
||||||
func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if err := validateEqualArgs(expected, actual); err != nil {
|
if err := validateEqualArgs(expected, actual); err != nil {
|
||||||
return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)",
|
return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)",
|
||||||
expected, actual, err), msgAndArgs...)
|
expected, actual, err), msgAndArgs...)
|
||||||
@ -349,6 +367,9 @@ func formatUnequalValues(expected, actual interface{}) (e string, a string) {
|
|||||||
//
|
//
|
||||||
// assert.EqualValues(t, uint32(123), int32(123))
|
// assert.EqualValues(t, uint32(123), int32(123))
|
||||||
func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
if !ObjectsAreEqualValues(expected, actual) {
|
if !ObjectsAreEqualValues(expected, actual) {
|
||||||
diff := diff(expected, actual)
|
diff := diff(expected, actual)
|
||||||
@ -366,12 +387,15 @@ func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interfa
|
|||||||
//
|
//
|
||||||
// assert.Exactly(t, int32(123), int64(123))
|
// assert.Exactly(t, int32(123), int64(123))
|
||||||
func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
aType := reflect.TypeOf(expected)
|
aType := reflect.TypeOf(expected)
|
||||||
bType := reflect.TypeOf(actual)
|
bType := reflect.TypeOf(actual)
|
||||||
|
|
||||||
if aType != bType {
|
if aType != bType {
|
||||||
return Fail(t, fmt.Sprintf("Types expected to match exactly\n\r\t%v != %v", aType, bType), msgAndArgs...)
|
return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Equal(t, expected, actual, msgAndArgs...)
|
return Equal(t, expected, actual, msgAndArgs...)
|
||||||
@ -382,6 +406,9 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
|
|||||||
//
|
//
|
||||||
// assert.NotNil(t, err)
|
// assert.NotNil(t, err)
|
||||||
func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if !isNil(object) {
|
if !isNil(object) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -407,6 +434,9 @@ func isNil(object interface{}) bool {
|
|||||||
//
|
//
|
||||||
// assert.Nil(t, err)
|
// assert.Nil(t, err)
|
||||||
func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if isNil(object) {
|
if isNil(object) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -446,6 +476,9 @@ func isEmpty(object interface{}) bool {
|
|||||||
//
|
//
|
||||||
// assert.Empty(t, obj)
|
// assert.Empty(t, obj)
|
||||||
func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
pass := isEmpty(object)
|
pass := isEmpty(object)
|
||||||
if !pass {
|
if !pass {
|
||||||
@ -463,6 +496,9 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
|||||||
// assert.Equal(t, "two", obj[1])
|
// assert.Equal(t, "two", obj[1])
|
||||||
// }
|
// }
|
||||||
func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
pass := !isEmpty(object)
|
pass := !isEmpty(object)
|
||||||
if !pass {
|
if !pass {
|
||||||
@ -490,6 +526,9 @@ func getLen(x interface{}) (ok bool, length int) {
|
|||||||
//
|
//
|
||||||
// assert.Len(t, mySlice, 3)
|
// assert.Len(t, mySlice, 3)
|
||||||
func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {
|
func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
ok, l := getLen(object)
|
ok, l := getLen(object)
|
||||||
if !ok {
|
if !ok {
|
||||||
return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
|
return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
|
||||||
@ -505,6 +544,14 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{})
|
|||||||
//
|
//
|
||||||
// assert.True(t, myBool)
|
// assert.True(t, myBool)
|
||||||
func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
if h, ok := t.(interface {
|
||||||
|
Helper()
|
||||||
|
}); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
if value != true {
|
if value != true {
|
||||||
return Fail(t, "Should be true", msgAndArgs...)
|
return Fail(t, "Should be true", msgAndArgs...)
|
||||||
@ -518,6 +565,9 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// assert.False(t, myBool)
|
// assert.False(t, myBool)
|
||||||
func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
if value != false {
|
if value != false {
|
||||||
return Fail(t, "Should be false", msgAndArgs...)
|
return Fail(t, "Should be false", msgAndArgs...)
|
||||||
@ -534,6 +584,9 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
|
|||||||
// Pointer variable equality is determined based on the equality of the
|
// Pointer variable equality is determined based on the equality of the
|
||||||
// referenced values (as opposed to the memory addresses).
|
// referenced values (as opposed to the memory addresses).
|
||||||
func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if err := validateEqualArgs(expected, actual); err != nil {
|
if err := validateEqualArgs(expected, actual); err != nil {
|
||||||
return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)",
|
return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)",
|
||||||
expected, actual, err), msgAndArgs...)
|
expected, actual, err), msgAndArgs...)
|
||||||
@ -592,6 +645,9 @@ func includeElement(list interface{}, element interface{}) (ok, found bool) {
|
|||||||
// assert.Contains(t, ["Hello", "World"], "World")
|
// assert.Contains(t, ["Hello", "World"], "World")
|
||||||
// assert.Contains(t, {"Hello": "World"}, "Hello")
|
// assert.Contains(t, {"Hello": "World"}, "Hello")
|
||||||
func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
|
func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
ok, found := includeElement(s, contains)
|
ok, found := includeElement(s, contains)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -612,6 +668,9 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo
|
|||||||
// assert.NotContains(t, ["Hello", "World"], "Earth")
|
// assert.NotContains(t, ["Hello", "World"], "Earth")
|
||||||
// assert.NotContains(t, {"Hello": "World"}, "Earth")
|
// assert.NotContains(t, {"Hello": "World"}, "Earth")
|
||||||
func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
|
func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
ok, found := includeElement(s, contains)
|
ok, found := includeElement(s, contains)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -630,6 +689,9 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
|
|||||||
//
|
//
|
||||||
// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
|
// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
|
||||||
func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
|
func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if subset == nil {
|
if subset == nil {
|
||||||
return true // we consider nil to be equal to the nil set
|
return true // we consider nil to be equal to the nil set
|
||||||
}
|
}
|
||||||
@ -671,6 +733,9 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
|
|||||||
//
|
//
|
||||||
// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
|
// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
|
||||||
func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
|
func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if subset == nil {
|
if subset == nil {
|
||||||
return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...)
|
return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...)
|
||||||
}
|
}
|
||||||
@ -713,6 +778,9 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
|
|||||||
//
|
//
|
||||||
// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])
|
// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])
|
||||||
func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {
|
func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if isEmpty(listA) && isEmpty(listB) {
|
if isEmpty(listA) && isEmpty(listB) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -763,6 +831,9 @@ func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface
|
|||||||
|
|
||||||
// Condition uses a Comparison to assert a complex condition.
|
// Condition uses a Comparison to assert a complex condition.
|
||||||
func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
|
func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
result := comp()
|
result := comp()
|
||||||
if !result {
|
if !result {
|
||||||
Fail(t, "Condition failed!", msgAndArgs...)
|
Fail(t, "Condition failed!", msgAndArgs...)
|
||||||
@ -800,9 +871,12 @@ func didPanic(f PanicTestFunc) (bool, interface{}) {
|
|||||||
//
|
//
|
||||||
// assert.Panics(t, func(){ GoCrazy() })
|
// assert.Panics(t, func(){ GoCrazy() })
|
||||||
func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
if funcDidPanic, panicValue := didPanic(f); !funcDidPanic {
|
if funcDidPanic, panicValue := didPanic(f); !funcDidPanic {
|
||||||
return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
|
return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -813,13 +887,16 @@ func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() })
|
// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() })
|
||||||
func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
funcDidPanic, panicValue := didPanic(f)
|
funcDidPanic, panicValue := didPanic(f)
|
||||||
if !funcDidPanic {
|
if !funcDidPanic {
|
||||||
return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
|
return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
|
||||||
}
|
}
|
||||||
if panicValue != expected {
|
if panicValue != expected {
|
||||||
return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%v\n\r\tPanic value:\t%v", f, expected, panicValue), msgAndArgs...)
|
return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v", f, expected, panicValue), msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -829,9 +906,12 @@ func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndAr
|
|||||||
//
|
//
|
||||||
// assert.NotPanics(t, func(){ RemainCalm() })
|
// assert.NotPanics(t, func(){ RemainCalm() })
|
||||||
func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
if funcDidPanic, panicValue := didPanic(f); funcDidPanic {
|
if funcDidPanic, panicValue := didPanic(f); funcDidPanic {
|
||||||
return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
|
return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v", f, panicValue), msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -841,6 +921,9 @@ func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
|
// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
|
||||||
func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
|
func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
dt := expected.Sub(actual)
|
dt := expected.Sub(actual)
|
||||||
if dt < -delta || dt > delta {
|
if dt < -delta || dt > delta {
|
||||||
@ -890,6 +973,9 @@ func toFloat(x interface{}) (float64, bool) {
|
|||||||
//
|
//
|
||||||
// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
|
// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
|
||||||
func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
af, aok := toFloat(expected)
|
af, aok := toFloat(expected)
|
||||||
bf, bok := toFloat(actual)
|
bf, bok := toFloat(actual)
|
||||||
@ -916,6 +1002,9 @@ func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs
|
|||||||
|
|
||||||
// InDeltaSlice is the same as InDelta, except it compares two slices.
|
// InDeltaSlice is the same as InDelta, except it compares two slices.
|
||||||
func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if expected == nil || actual == nil ||
|
if expected == nil || actual == nil ||
|
||||||
reflect.TypeOf(actual).Kind() != reflect.Slice ||
|
reflect.TypeOf(actual).Kind() != reflect.Slice ||
|
||||||
reflect.TypeOf(expected).Kind() != reflect.Slice {
|
reflect.TypeOf(expected).Kind() != reflect.Slice {
|
||||||
@ -937,6 +1026,9 @@ func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAn
|
|||||||
|
|
||||||
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
|
||||||
func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if expected == nil || actual == nil ||
|
if expected == nil || actual == nil ||
|
||||||
reflect.TypeOf(actual).Kind() != reflect.Map ||
|
reflect.TypeOf(actual).Kind() != reflect.Map ||
|
||||||
reflect.TypeOf(expected).Kind() != reflect.Map {
|
reflect.TypeOf(expected).Kind() != reflect.Map {
|
||||||
@ -994,6 +1086,9 @@ func calcRelativeError(expected, actual interface{}) (float64, error) {
|
|||||||
|
|
||||||
// InEpsilon asserts that expected and actual have a relative error less than epsilon
|
// InEpsilon asserts that expected and actual have a relative error less than epsilon
|
||||||
func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
|
func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
actualEpsilon, err := calcRelativeError(expected, actual)
|
actualEpsilon, err := calcRelativeError(expected, actual)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Fail(t, err.Error(), msgAndArgs...)
|
return Fail(t, err.Error(), msgAndArgs...)
|
||||||
@ -1008,6 +1103,9 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd
|
|||||||
|
|
||||||
// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
|
// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
|
||||||
func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
|
func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if expected == nil || actual == nil ||
|
if expected == nil || actual == nil ||
|
||||||
reflect.TypeOf(actual).Kind() != reflect.Slice ||
|
reflect.TypeOf(actual).Kind() != reflect.Slice ||
|
||||||
reflect.TypeOf(expected).Kind() != reflect.Slice {
|
reflect.TypeOf(expected).Kind() != reflect.Slice {
|
||||||
@ -1038,6 +1136,9 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m
|
|||||||
// assert.Equal(t, expectedObj, actualObj)
|
// assert.Equal(t, expectedObj, actualObj)
|
||||||
// }
|
// }
|
||||||
func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
|
func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...)
|
return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...)
|
||||||
}
|
}
|
||||||
@ -1052,6 +1153,9 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
|
|||||||
// assert.Equal(t, expectedError, err)
|
// assert.Equal(t, expectedError, err)
|
||||||
// }
|
// }
|
||||||
func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
|
func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return Fail(t, "An error is expected but got nil.", msgAndArgs...)
|
return Fail(t, "An error is expected but got nil.", msgAndArgs...)
|
||||||
@ -1066,6 +1170,9 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
|
|||||||
// actualObj, err := SomeFunction()
|
// actualObj, err := SomeFunction()
|
||||||
// assert.EqualError(t, err, expectedErrorString)
|
// assert.EqualError(t, err, expectedErrorString)
|
||||||
func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {
|
func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if !Error(t, theError, msgAndArgs...) {
|
if !Error(t, theError, msgAndArgs...) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -1099,6 +1206,9 @@ func matchRegexp(rx interface{}, str interface{}) bool {
|
|||||||
// assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
|
// assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
|
||||||
// assert.Regexp(t, "start...$", "it's not starting")
|
// assert.Regexp(t, "start...$", "it's not starting")
|
||||||
func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
|
func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
|
||||||
match := matchRegexp(rx, str)
|
match := matchRegexp(rx, str)
|
||||||
|
|
||||||
@ -1114,6 +1224,9 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface
|
|||||||
// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
|
// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
|
||||||
// assert.NotRegexp(t, "^start", "it's not starting")
|
// assert.NotRegexp(t, "^start", "it's not starting")
|
||||||
func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
|
func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
match := matchRegexp(rx, str)
|
match := matchRegexp(rx, str)
|
||||||
|
|
||||||
if match {
|
if match {
|
||||||
@ -1126,6 +1239,9 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf
|
|||||||
|
|
||||||
// Zero asserts that i is the zero value for its type.
|
// Zero asserts that i is the zero value for its type.
|
||||||
func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
|
func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
|
if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
|
||||||
return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...)
|
return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...)
|
||||||
}
|
}
|
||||||
@ -1134,6 +1250,9 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
|
|||||||
|
|
||||||
// NotZero asserts that i is not the zero value for its type.
|
// NotZero asserts that i is not the zero value for its type.
|
||||||
func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
|
func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
|
if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
|
||||||
return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...)
|
return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...)
|
||||||
}
|
}
|
||||||
@ -1142,6 +1261,9 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
|
|||||||
|
|
||||||
// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
|
||||||
func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
|
func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
info, err := os.Lstat(path)
|
info, err := os.Lstat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
@ -1157,6 +1279,9 @@ func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
|
|||||||
|
|
||||||
// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
|
||||||
func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
|
func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
info, err := os.Lstat(path)
|
info, err := os.Lstat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
@ -1174,6 +1299,9 @@ func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
|
|||||||
//
|
//
|
||||||
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||||
func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
|
func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
var expectedJSONAsInterface, actualJSONAsInterface interface{}
|
var expectedJSONAsInterface, actualJSONAsInterface interface{}
|
||||||
|
|
||||||
if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {
|
if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {
|
||||||
@ -1212,12 +1340,18 @@ func diff(expected interface{}, actual interface{}) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array {
|
if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
e := spewConfig.Sdump(expected)
|
var e, a string
|
||||||
a := spewConfig.Sdump(actual)
|
if ek != reflect.String {
|
||||||
|
e = spewConfig.Sdump(expected)
|
||||||
|
a = spewConfig.Sdump(actual)
|
||||||
|
} else {
|
||||||
|
e = expected.(string)
|
||||||
|
a = actual.(string)
|
||||||
|
}
|
||||||
|
|
||||||
diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
|
diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
|
||||||
A: difflib.SplitLines(e),
|
A: difflib.SplitLines(e),
|
||||||
@ -1254,3 +1388,7 @@ var spewConfig = spew.ConfigState{
|
|||||||
DisableCapacities: true,
|
DisableCapacities: true,
|
||||||
SortKeys: true,
|
SortKeys: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type tHelper interface {
|
||||||
|
Helper()
|
||||||
|
}
|
||||||
|
22
vendor/github.com/stretchr/testify/assert/http_assertions.go
generated
vendored
22
vendor/github.com/stretchr/testify/assert/http_assertions.go
generated
vendored
@ -12,10 +12,11 @@ import (
|
|||||||
// an error if building a new request fails.
|
// an error if building a new request fails.
|
||||||
func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) {
|
func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
|
req, err := http.NewRequest(method, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
req.URL.RawQuery = values.Encode()
|
||||||
handler(w, req)
|
handler(w, req)
|
||||||
return w.Code, nil
|
return w.Code, nil
|
||||||
}
|
}
|
||||||
@ -26,6 +27,9 @@ func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
code, err := httpCode(handler, method, url, values)
|
code, err := httpCode(handler, method, url, values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
||||||
@ -46,6 +50,9 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
code, err := httpCode(handler, method, url, values)
|
code, err := httpCode(handler, method, url, values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
||||||
@ -66,6 +73,9 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu
|
|||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
code, err := httpCode(handler, method, url, values)
|
code, err := httpCode(handler, method, url, values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
||||||
@ -95,10 +105,13 @@ func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) s
|
|||||||
// HTTPBodyContains asserts that a specified handler returns a
|
// HTTPBodyContains asserts that a specified handler returns a
|
||||||
// body that contains a string.
|
// body that contains a string.
|
||||||
//
|
//
|
||||||
// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
body := HTTPBody(handler, method, url, values)
|
body := HTTPBody(handler, method, url, values)
|
||||||
|
|
||||||
contains := strings.Contains(body, fmt.Sprint(str))
|
contains := strings.Contains(body, fmt.Sprint(str))
|
||||||
@ -112,10 +125,13 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string,
|
|||||||
// HTTPBodyNotContains asserts that a specified handler returns a
|
// HTTPBodyNotContains asserts that a specified handler returns a
|
||||||
// body that does not contain a string.
|
// body that does not contain a string.
|
||||||
//
|
//
|
||||||
// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
|
// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||||
//
|
//
|
||||||
// Returns whether the assertion was successful (true) or not (false).
|
// Returns whether the assertion was successful (true) or not (false).
|
||||||
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
body := HTTPBody(handler, method, url, values)
|
body := HTTPBody(handler, method, url, values)
|
||||||
|
|
||||||
contains := strings.Contains(body, fmt.Sprint(str))
|
contains := strings.Contains(body, fmt.Sprint(str))
|
||||||
|
4
vendor/github.com/zyedidia/clipboard/LICENSE
generated
vendored
4
vendor/github.com/zyedidia/clipboard/LICENSE
generated
vendored
@ -1,3 +1,7 @@
|
|||||||
|
Copyright (c) 2018 Zachary Yedidia. Modifications to atotto/clipboard.
|
||||||
|
|
||||||
|
Original license:
|
||||||
|
|
||||||
Copyright (c) 2013 Ato Araki. All rights reserved.
|
Copyright (c) 2013 Ato Araki. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
4
vendor/github.com/zyedidia/clipboard/README.md
generated
vendored
4
vendor/github.com/zyedidia/clipboard/README.md
generated
vendored
@ -1,3 +1,7 @@
|
|||||||
|
# This is a fork of atotto/clipboard
|
||||||
|
|
||||||
|
This fork is used for `zyedidia/micro` and has some modifications, namely: support for the primary clipboard on linux and support for an internal clipboard if the system clipboard is not available.
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/atotto/clipboard.svg?branch=master)](https://travis-ci.org/atotto/clipboard) [![Build Status](https://drone.io/github.com/atotto/clipboard/status.png)](https://drone.io/github.com/atotto/clipboard/latest)
|
[![Build Status](https://travis-ci.org/atotto/clipboard.svg?branch=master)](https://travis-ci.org/atotto/clipboard) [![Build Status](https://drone.io/github.com/atotto/clipboard/status.png)](https://drone.io/github.com/atotto/clipboard/latest)
|
||||||
|
|
||||||
[![GoDoc](https://godoc.org/github.com/atotto/clipboard?status.svg)](http://godoc.org/github.com/atotto/clipboard)
|
[![GoDoc](https://godoc.org/github.com/atotto/clipboard?status.svg)](http://godoc.org/github.com/atotto/clipboard)
|
||||||
|
122
vendor/golang.org/x/image/bmp/writer.go
generated
vendored
122
vendor/golang.org/x/image/bmp/writer.go
generated
vendored
@ -49,20 +49,91 @@ func encodePaletted(w io.Writer, pix []uint8, dx, dy, stride, step int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int) error {
|
func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error {
|
||||||
buf := make([]byte, step)
|
buf := make([]byte, step)
|
||||||
for y := dy - 1; y >= 0; y-- {
|
if opaque {
|
||||||
min := y*stride + 0
|
for y := dy - 1; y >= 0; y-- {
|
||||||
max := y*stride + dx*4
|
min := y*stride + 0
|
||||||
off := 0
|
max := y*stride + dx*4
|
||||||
for i := min; i < max; i += 4 {
|
off := 0
|
||||||
buf[off+2] = pix[i+0]
|
for i := min; i < max; i += 4 {
|
||||||
buf[off+1] = pix[i+1]
|
buf[off+2] = pix[i+0]
|
||||||
buf[off+0] = pix[i+2]
|
buf[off+1] = pix[i+1]
|
||||||
off += 3
|
buf[off+0] = pix[i+2]
|
||||||
|
off += 3
|
||||||
|
}
|
||||||
|
if _, err := w.Write(buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if _, err := w.Write(buf); err != nil {
|
} else {
|
||||||
return err
|
for y := dy - 1; y >= 0; y-- {
|
||||||
|
min := y*stride + 0
|
||||||
|
max := y*stride + dx*4
|
||||||
|
off := 0
|
||||||
|
for i := min; i < max; i += 4 {
|
||||||
|
a := uint32(pix[i+3])
|
||||||
|
if a == 0 {
|
||||||
|
buf[off+2] = 0
|
||||||
|
buf[off+1] = 0
|
||||||
|
buf[off+0] = 0
|
||||||
|
buf[off+3] = 0
|
||||||
|
off += 4
|
||||||
|
continue
|
||||||
|
} else if a == 0xff {
|
||||||
|
buf[off+2] = pix[i+0]
|
||||||
|
buf[off+1] = pix[i+1]
|
||||||
|
buf[off+0] = pix[i+2]
|
||||||
|
buf[off+3] = 0xff
|
||||||
|
off += 4
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buf[off+2] = uint8(((uint32(pix[i+0]) * 0xffff) / a) >> 8)
|
||||||
|
buf[off+1] = uint8(((uint32(pix[i+1]) * 0xffff) / a) >> 8)
|
||||||
|
buf[off+0] = uint8(((uint32(pix[i+2]) * 0xffff) / a) >> 8)
|
||||||
|
buf[off+3] = uint8(a)
|
||||||
|
off += 4
|
||||||
|
}
|
||||||
|
if _, err := w.Write(buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeNRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error {
|
||||||
|
buf := make([]byte, step)
|
||||||
|
if opaque {
|
||||||
|
for y := dy - 1; y >= 0; y-- {
|
||||||
|
min := y*stride + 0
|
||||||
|
max := y*stride + dx*4
|
||||||
|
off := 0
|
||||||
|
for i := min; i < max; i += 4 {
|
||||||
|
buf[off+2] = pix[i+0]
|
||||||
|
buf[off+1] = pix[i+1]
|
||||||
|
buf[off+0] = pix[i+2]
|
||||||
|
off += 3
|
||||||
|
}
|
||||||
|
if _, err := w.Write(buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for y := dy - 1; y >= 0; y-- {
|
||||||
|
min := y*stride + 0
|
||||||
|
max := y*stride + dx*4
|
||||||
|
off := 0
|
||||||
|
for i := min; i < max; i += 4 {
|
||||||
|
buf[off+2] = pix[i+0]
|
||||||
|
buf[off+1] = pix[i+1]
|
||||||
|
buf[off+0] = pix[i+2]
|
||||||
|
buf[off+3] = pix[i+3]
|
||||||
|
off += 4
|
||||||
|
}
|
||||||
|
if _, err := w.Write(buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -105,6 +176,7 @@ func Encode(w io.Writer, m image.Image) error {
|
|||||||
|
|
||||||
var step int
|
var step int
|
||||||
var palette []byte
|
var palette []byte
|
||||||
|
var opaque bool
|
||||||
switch m := m.(type) {
|
switch m := m.(type) {
|
||||||
case *image.Gray:
|
case *image.Gray:
|
||||||
step = (d.X + 3) &^ 3
|
step = (d.X + 3) &^ 3
|
||||||
@ -134,6 +206,28 @@ func Encode(w io.Writer, m image.Image) error {
|
|||||||
h.fileSize += uint32(len(palette)) + h.imageSize
|
h.fileSize += uint32(len(palette)) + h.imageSize
|
||||||
h.pixOffset += uint32(len(palette))
|
h.pixOffset += uint32(len(palette))
|
||||||
h.bpp = 8
|
h.bpp = 8
|
||||||
|
case *image.RGBA:
|
||||||
|
opaque = m.Opaque()
|
||||||
|
if opaque {
|
||||||
|
step = (3*d.X + 3) &^ 3
|
||||||
|
h.bpp = 24
|
||||||
|
} else {
|
||||||
|
step = 4 * d.X
|
||||||
|
h.bpp = 32
|
||||||
|
}
|
||||||
|
h.imageSize = uint32(d.Y * step)
|
||||||
|
h.fileSize += h.imageSize
|
||||||
|
case *image.NRGBA:
|
||||||
|
opaque = m.Opaque()
|
||||||
|
if opaque {
|
||||||
|
step = (3*d.X + 3) &^ 3
|
||||||
|
h.bpp = 24
|
||||||
|
} else {
|
||||||
|
step = 4 * d.X
|
||||||
|
h.bpp = 32
|
||||||
|
}
|
||||||
|
h.imageSize = uint32(d.Y * step)
|
||||||
|
h.fileSize += h.imageSize
|
||||||
default:
|
default:
|
||||||
step = (3*d.X + 3) &^ 3
|
step = (3*d.X + 3) &^ 3
|
||||||
h.imageSize = uint32(d.Y * step)
|
h.imageSize = uint32(d.Y * step)
|
||||||
@ -160,7 +254,9 @@ func Encode(w io.Writer, m image.Image) error {
|
|||||||
case *image.Paletted:
|
case *image.Paletted:
|
||||||
return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step)
|
return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step)
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
||||||
return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step)
|
return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque)
|
||||||
|
case *image.NRGBA:
|
||||||
|
return encodeNRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque)
|
||||||
}
|
}
|
||||||
return encode(w, m, step)
|
return encode(w, m, step)
|
||||||
}
|
}
|
||||||
|
103
vendor/golang.org/x/net/html/parse.go
generated
vendored
103
vendor/golang.org/x/net/html/parse.go
generated
vendored
@ -209,27 +209,6 @@ loop:
|
|||||||
p.oe = p.oe[:i+1]
|
p.oe = p.oe[:i+1]
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateAllImpliedEndTags pops nodes off the stack of open elements as long as
|
|
||||||
// the top node has a tag name of caption, colgroup, dd, div, dt, li, optgroup, option, p, rb,
|
|
||||||
// rp, rt, rtc, span, tbody, td, tfoot, th, thead or tr.
|
|
||||||
func (p *parser) generateAllImpliedEndTags() {
|
|
||||||
var i int
|
|
||||||
for i = len(p.oe) - 1; i >= 0; i-- {
|
|
||||||
n := p.oe[i]
|
|
||||||
if n.Type == ElementNode {
|
|
||||||
switch n.DataAtom {
|
|
||||||
// TODO: remove this divergence from the HTML5 spec
|
|
||||||
case a.Caption, a.Colgroup, a.Dd, a.Div, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb,
|
|
||||||
a.Rp, a.Rt, a.Rtc, a.Span, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
p.oe = p.oe[:i+1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// addChild adds a child node n to the top element, and pushes n onto the stack
|
// addChild adds a child node n to the top element, and pushes n onto the stack
|
||||||
// of open elements if it is an element node.
|
// of open elements if it is an element node.
|
||||||
func (p *parser) addChild(n *Node) {
|
func (p *parser) addChild(n *Node) {
|
||||||
@ -276,7 +255,7 @@ func (p *parser) fosterParent(n *Node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if template != nil && (table == nil || j < i) {
|
if template != nil && (table == nil || j > i) {
|
||||||
template.AppendChild(n)
|
template.AppendChild(n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -679,11 +658,16 @@ func inHeadIM(p *parser) bool {
|
|||||||
if !p.oe.contains(a.Template) {
|
if !p.oe.contains(a.Template) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
p.generateAllImpliedEndTags()
|
// TODO: remove this divergence from the HTML5 spec.
|
||||||
if n := p.oe.top(); n.DataAtom != a.Template {
|
//
|
||||||
return true
|
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
|
||||||
|
p.generateImpliedEndTags()
|
||||||
|
for i := len(p.oe) - 1; i >= 0; i-- {
|
||||||
|
if n := p.oe[i]; n.Namespace == "" && n.DataAtom == a.Template {
|
||||||
|
p.oe = p.oe[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p.popUntil(defaultScope, a.Template)
|
|
||||||
p.clearActiveFormattingElements()
|
p.clearActiveFormattingElements()
|
||||||
p.templateStack.pop()
|
p.templateStack.pop()
|
||||||
p.resetInsertionMode()
|
p.resetInsertionMode()
|
||||||
@ -860,9 +844,13 @@ func inBodyIM(p *parser) bool {
|
|||||||
// The newline, if any, will be dealt with by the TextToken case.
|
// The newline, if any, will be dealt with by the TextToken case.
|
||||||
p.framesetOK = false
|
p.framesetOK = false
|
||||||
case a.Form:
|
case a.Form:
|
||||||
if p.oe.contains(a.Template) || p.form == nil {
|
if p.form != nil && !p.oe.contains(a.Template) {
|
||||||
p.popUntil(buttonScope, a.P)
|
// Ignore the token
|
||||||
p.addElement()
|
return true
|
||||||
|
}
|
||||||
|
p.popUntil(buttonScope, a.P)
|
||||||
|
p.addElement()
|
||||||
|
if !p.oe.contains(a.Template) {
|
||||||
p.form = p.top()
|
p.form = p.top()
|
||||||
}
|
}
|
||||||
case a.Li:
|
case a.Li:
|
||||||
@ -1070,13 +1058,7 @@ func inBodyIM(p *parser) bool {
|
|||||||
p.acknowledgeSelfClosingTag()
|
p.acknowledgeSelfClosingTag()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
case a.Frame:
|
case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
|
||||||
// TODO: remove this divergence from the HTML5 spec.
|
|
||||||
if p.oe.contains(a.Template) {
|
|
||||||
p.addElement()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case a.Caption, a.Col, a.Colgroup, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
|
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
default:
|
default:
|
||||||
p.reconstructActiveFormattingElements()
|
p.reconstructActiveFormattingElements()
|
||||||
@ -1098,12 +1080,13 @@ func inBodyIM(p *parser) bool {
|
|||||||
p.popUntil(defaultScope, p.tok.DataAtom)
|
p.popUntil(defaultScope, p.tok.DataAtom)
|
||||||
case a.Form:
|
case a.Form:
|
||||||
if p.oe.contains(a.Template) {
|
if p.oe.contains(a.Template) {
|
||||||
if !p.oe.contains(a.Form) {
|
i := p.indexOfElementInScope(defaultScope, a.Form)
|
||||||
|
if i == -1 {
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
p.generateImpliedEndTags()
|
p.generateImpliedEndTags()
|
||||||
if p.tok.DataAtom == a.Form {
|
if p.oe[i].DataAtom != a.Form {
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -1346,9 +1329,6 @@ func textIM(p *parser) bool {
|
|||||||
// Section 12.2.6.4.9.
|
// Section 12.2.6.4.9.
|
||||||
func inTableIM(p *parser) bool {
|
func inTableIM(p *parser) bool {
|
||||||
switch p.tok.Type {
|
switch p.tok.Type {
|
||||||
case ErrorToken:
|
|
||||||
// Stop parsing.
|
|
||||||
return true
|
|
||||||
case TextToken:
|
case TextToken:
|
||||||
p.tok.Data = strings.Replace(p.tok.Data, "\x00", "", -1)
|
p.tok.Data = strings.Replace(p.tok.Data, "\x00", "", -1)
|
||||||
switch p.oe.top().DataAtom {
|
switch p.oe.top().DataAtom {
|
||||||
@ -1443,6 +1423,8 @@ func inTableIM(p *parser) bool {
|
|||||||
case DoctypeToken:
|
case DoctypeToken:
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
|
case ErrorToken:
|
||||||
|
return inBodyIM(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.fosterParenting = true
|
p.fosterParenting = true
|
||||||
@ -1545,6 +1527,8 @@ func inColumnGroupIM(p *parser) bool {
|
|||||||
case a.Template:
|
case a.Template:
|
||||||
return inHeadIM(p)
|
return inHeadIM(p)
|
||||||
}
|
}
|
||||||
|
case ErrorToken:
|
||||||
|
return inBodyIM(p)
|
||||||
}
|
}
|
||||||
if p.oe.top().DataAtom != a.Colgroup {
|
if p.oe.top().DataAtom != a.Colgroup {
|
||||||
return true
|
return true
|
||||||
@ -1709,9 +1693,6 @@ func inCellIM(p *parser) bool {
|
|||||||
// Section 12.2.6.4.16.
|
// Section 12.2.6.4.16.
|
||||||
func inSelectIM(p *parser) bool {
|
func inSelectIM(p *parser) bool {
|
||||||
switch p.tok.Type {
|
switch p.tok.Type {
|
||||||
case ErrorToken:
|
|
||||||
// Stop parsing.
|
|
||||||
return true
|
|
||||||
case TextToken:
|
case TextToken:
|
||||||
p.addText(strings.Replace(p.tok.Data, "\x00", "", -1))
|
p.addText(strings.Replace(p.tok.Data, "\x00", "", -1))
|
||||||
case StartTagToken:
|
case StartTagToken:
|
||||||
@ -1775,6 +1756,8 @@ func inSelectIM(p *parser) bool {
|
|||||||
case DoctypeToken:
|
case DoctypeToken:
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
|
case ErrorToken:
|
||||||
|
return inBodyIM(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -1841,15 +1824,26 @@ func inTemplateIM(p *parser) bool {
|
|||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
case ErrorToken:
|
||||||
|
if !p.oe.contains(a.Template) {
|
||||||
|
// Ignore the token.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// TODO: remove this divergence from the HTML5 spec.
|
||||||
|
//
|
||||||
|
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
|
||||||
|
p.generateImpliedEndTags()
|
||||||
|
for i := len(p.oe) - 1; i >= 0; i-- {
|
||||||
|
if n := p.oe[i]; n.Namespace == "" && n.DataAtom == a.Template {
|
||||||
|
p.oe = p.oe[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.clearActiveFormattingElements()
|
||||||
|
p.templateStack.pop()
|
||||||
|
p.resetInsertionMode()
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
if !p.oe.contains(a.Template) {
|
|
||||||
// Ignore the token.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
p.popUntil(defaultScope, a.Template)
|
|
||||||
p.clearActiveFormattingElements()
|
|
||||||
p.templateStack.pop()
|
|
||||||
p.resetInsertionMode()
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1923,11 +1917,6 @@ func inFramesetIM(p *parser) bool {
|
|||||||
p.acknowledgeSelfClosingTag()
|
p.acknowledgeSelfClosingTag()
|
||||||
case a.Noframes:
|
case a.Noframes:
|
||||||
return inHeadIM(p)
|
return inHeadIM(p)
|
||||||
case a.Template:
|
|
||||||
// TODO: remove this divergence from the HTML5 spec.
|
|
||||||
//
|
|
||||||
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
|
|
||||||
return inTemplateIM(p)
|
|
||||||
}
|
}
|
||||||
case EndTagToken:
|
case EndTagToken:
|
||||||
switch p.tok.DataAtom {
|
switch p.tok.DataAtom {
|
||||||
|
5
vendor/gopkg.in/toast.v1/toast.go
generated
vendored
5
vendor/gopkg.in/toast.v1/toast.go
generated
vendored
@ -11,6 +11,7 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/nu7hatch/gouuid"
|
"github.com/nu7hatch/gouuid"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
var toastTemplate *template.Template
|
var toastTemplate *template.Template
|
||||||
@ -347,7 +348,9 @@ func invokeTemporaryScript(content string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = exec.Command("PowerShell", "-ExecutionPolicy", "Bypass", "-File", file).Run(); err != nil {
|
cmd := exec.Command("PowerShell", "-ExecutionPolicy", "Bypass", "-File", file)
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||||
|
if err = cmd.Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
145
vendor/maunium.net/go/gomatrix/client.go
generated
vendored
145
vendor/maunium.net/go/gomatrix/client.go
generated
vendored
@ -6,13 +6,16 @@ package gomatrix
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"maunium.net/go/maulogger"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -26,6 +29,7 @@ type Client struct {
|
|||||||
Client *http.Client // The underlying HTTP client which will be used to make HTTP requests.
|
Client *http.Client // The underlying HTTP client which will be used to make HTTP requests.
|
||||||
Syncer Syncer // The thing which can process /sync responses
|
Syncer Syncer // The thing which can process /sync responses
|
||||||
Store Storer // The thing which can store rooms/tokens/ids
|
Store Storer // The thing which can store rooms/tokens/ids
|
||||||
|
Logger maulogger.Logger
|
||||||
|
|
||||||
// The ?user_id= query parameter for application services. This must be set *prior* to calling a method. If this is empty,
|
// The ?user_id= query parameter for application services. This must be set *prior* to calling a method. If this is empty,
|
||||||
// no user_id parameter will be sent.
|
// no user_id parameter will be sent.
|
||||||
@ -39,6 +43,7 @@ type Client struct {
|
|||||||
// HTTPError An HTTP Error response, which may wrap an underlying native Go Error.
|
// HTTPError An HTTP Error response, which may wrap an underlying native Go Error.
|
||||||
type HTTPError struct {
|
type HTTPError struct {
|
||||||
WrappedError error
|
WrappedError error
|
||||||
|
RespError *RespError
|
||||||
Message string
|
Message string
|
||||||
Code int
|
Code int
|
||||||
}
|
}
|
||||||
@ -177,6 +182,14 @@ func (cli *Client) StopSync() {
|
|||||||
cli.incrementSyncingID()
|
cli.incrementSyncingID()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cli *Client) LogRequest(req *http.Request, body string) {
|
||||||
|
if cli.Logger == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cli.Logger.Debugfln("%s %s %s", req.Method, req.URL.Path, body)
|
||||||
|
}
|
||||||
|
|
||||||
// MakeRequest makes a JSON HTTP request to the given URL.
|
// MakeRequest makes a JSON HTTP request to the given URL.
|
||||||
// If "resBody" is not nil, the response body will be json.Unmarshalled into it.
|
// If "resBody" is not nil, the response body will be json.Unmarshalled into it.
|
||||||
//
|
//
|
||||||
@ -186,12 +199,14 @@ func (cli *Client) StopSync() {
|
|||||||
func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{}, resBody interface{}) ([]byte, error) {
|
func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{}, resBody interface{}) ([]byte, error) {
|
||||||
var req *http.Request
|
var req *http.Request
|
||||||
var err error
|
var err error
|
||||||
|
logBody := "{}"
|
||||||
if reqBody != nil {
|
if reqBody != nil {
|
||||||
var jsonStr []byte
|
var jsonStr []byte
|
||||||
jsonStr, err = json.Marshal(reqBody)
|
jsonStr, err = json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
logBody = string(jsonStr)
|
||||||
req, err = http.NewRequest(method, httpURL, bytes.NewBuffer(jsonStr))
|
req, err = http.NewRequest(method, httpURL, bytes.NewBuffer(jsonStr))
|
||||||
} else {
|
} else {
|
||||||
req, err = http.NewRequest(method, httpURL, nil)
|
req, err = http.NewRequest(method, httpURL, nil)
|
||||||
@ -201,6 +216,7 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
cli.LogRequest(req, logBody)
|
||||||
res, err := cli.Client.Do(req)
|
res, err := cli.Client.Do(req)
|
||||||
if res != nil {
|
if res != nil {
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
@ -211,9 +227,11 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{
|
|||||||
contents, err := ioutil.ReadAll(res.Body)
|
contents, err := ioutil.ReadAll(res.Body)
|
||||||
if res.StatusCode/100 != 2 { // not 2xx
|
if res.StatusCode/100 != 2 { // not 2xx
|
||||||
var wrap error
|
var wrap error
|
||||||
var respErr RespError
|
respErr := &RespError{}
|
||||||
if _ = json.Unmarshal(contents, &respErr); respErr.ErrCode != "" {
|
if _ = json.Unmarshal(contents, respErr); respErr.ErrCode != "" {
|
||||||
wrap = respErr
|
wrap = respErr
|
||||||
|
} else {
|
||||||
|
respErr = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we failed to decode as RespError, don't just drop the HTTP body, include it in the
|
// If we failed to decode as RespError, don't just drop the HTTP body, include it in the
|
||||||
@ -227,6 +245,7 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{
|
|||||||
Code: res.StatusCode,
|
Code: res.StatusCode,
|
||||||
Message: msg,
|
Message: msg,
|
||||||
WrappedError: wrap,
|
WrappedError: wrap,
|
||||||
|
RespError: respErr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -342,7 +361,7 @@ func (cli *Client) RegisterDummy(req *ReqRegister) (*RespRegister, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if res == nil {
|
if res == nil {
|
||||||
return nil, fmt.Errorf("registration failed: does this server support m.login.dummy?")
|
return nil, fmt.Errorf("registration failed: does this server support m.login.dummy? ")
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
@ -442,17 +461,38 @@ func (cli *Client) SetAvatarURL(url string) (err error) {
|
|||||||
|
|
||||||
// SendMessageEvent sends a message event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
|
// SendMessageEvent sends a message event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
|
||||||
// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
|
// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
|
||||||
func (cli *Client) SendMessageEvent(roomID string, eventType string, contentJSON interface{}) (resp *RespSendEvent, err error) {
|
func (cli *Client) SendMessageEvent(roomID string, eventType EventType, contentJSON interface{}) (resp *RespSendEvent, err error) {
|
||||||
txnID := txnID()
|
txnID := txnID()
|
||||||
urlPath := cli.BuildURL("rooms", roomID, "send", eventType, txnID)
|
urlPath := cli.BuildURL("rooms", roomID, "send", eventType.String(), txnID)
|
||||||
|
_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendMessageEvent sends a message event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
|
||||||
|
// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
|
||||||
|
func (cli *Client) SendMassagedMessageEvent(roomID string, eventType EventType, contentJSON interface{}, ts int64) (resp *RespSendEvent, err error) {
|
||||||
|
txnID := txnID()
|
||||||
|
urlPath := cli.BuildURLWithQuery([]string{"rooms", roomID, "send", eventType.String(), txnID}, map[string]string{
|
||||||
|
"ts": strconv.FormatInt(ts, 10),
|
||||||
|
})
|
||||||
_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
|
_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendStateEvent sends a state event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey
|
// SendStateEvent sends a state event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey
|
||||||
// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
|
// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
|
||||||
func (cli *Client) SendStateEvent(roomID, eventType, stateKey string, contentJSON interface{}) (resp *RespSendEvent, err error) {
|
func (cli *Client) SendStateEvent(roomID string, eventType EventType, stateKey string, contentJSON interface{}) (resp *RespSendEvent, err error) {
|
||||||
urlPath := cli.BuildURL("rooms", roomID, "state", eventType, stateKey)
|
urlPath := cli.BuildURL("rooms", roomID, "state", eventType.String(), stateKey)
|
||||||
|
_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendStateEvent sends a state event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey
|
||||||
|
// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
|
||||||
|
func (cli *Client) SendMassagedStateEvent(roomID string, eventType EventType, stateKey string, contentJSON interface{}, ts int64) (resp *RespSendEvent, err error) {
|
||||||
|
urlPath := cli.BuildURLWithQuery([]string{"rooms", roomID, "state", eventType.String(), stateKey}, map[string]string{
|
||||||
|
"ts": strconv.FormatInt(ts, 10),
|
||||||
|
})
|
||||||
_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
|
_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -460,37 +500,39 @@ func (cli *Client) SendStateEvent(roomID, eventType, stateKey string, contentJSO
|
|||||||
// SendText sends an m.room.message event into the given room with a msgtype of m.text
|
// SendText sends an m.room.message event into the given room with a msgtype of m.text
|
||||||
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-text
|
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-text
|
||||||
func (cli *Client) SendText(roomID, text string) (*RespSendEvent, error) {
|
func (cli *Client) SendText(roomID, text string) (*RespSendEvent, error) {
|
||||||
return cli.SendMessageEvent(roomID, "m.room.message",
|
return cli.SendMessageEvent(roomID, EventMessage, Content{
|
||||||
TextMessage{"m.text", text})
|
MsgType: MsgText,
|
||||||
|
Body: text,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendImage sends an m.room.message event into the given room with a msgtype of m.image
|
// SendImage sends an m.room.message event into the given room with a msgtype of m.image
|
||||||
// See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-image
|
// See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-image
|
||||||
func (cli *Client) SendImage(roomID, body, url string) (*RespSendEvent, error) {
|
func (cli *Client) SendImage(roomID, body, url string) (*RespSendEvent, error) {
|
||||||
return cli.SendMessageEvent(roomID, "m.room.message",
|
return cli.SendMessageEvent(roomID, EventMessage, Content{
|
||||||
ImageMessage{
|
MsgType: MsgImage,
|
||||||
MsgType: "m.image",
|
Body: body,
|
||||||
Body: body,
|
URL: url,
|
||||||
URL: url,
|
})
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendVideo sends an m.room.message event into the given room with a msgtype of m.video
|
// SendVideo sends an m.room.message event into the given room with a msgtype of m.video
|
||||||
// See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-video
|
// See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-video
|
||||||
func (cli *Client) SendVideo(roomID, body, url string) (*RespSendEvent, error) {
|
func (cli *Client) SendVideo(roomID, body, url string) (*RespSendEvent, error) {
|
||||||
return cli.SendMessageEvent(roomID, "m.room.message",
|
return cli.SendMessageEvent(roomID, EventMessage, Content{
|
||||||
VideoMessage{
|
MsgType: MsgVideo,
|
||||||
MsgType: "m.video",
|
Body: body,
|
||||||
Body: body,
|
URL: url,
|
||||||
URL: url,
|
})
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendNotice sends an m.room.message event into the given room with a msgtype of m.notice
|
// SendNotice sends an m.room.message event into the given room with a msgtype of m.notice
|
||||||
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-notice
|
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-notice
|
||||||
func (cli *Client) SendNotice(roomID, text string) (*RespSendEvent, error) {
|
func (cli *Client) SendNotice(roomID, text string) (*RespSendEvent, error) {
|
||||||
return cli.SendMessageEvent(roomID, "m.room.message",
|
return cli.SendMessageEvent(roomID, EventMessage, Content{
|
||||||
TextMessage{"m.notice", text})
|
MsgType: MsgNotice,
|
||||||
|
Body: text,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// RedactEvent redacts the given event. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
|
// RedactEvent redacts the given event. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
|
||||||
@ -569,11 +611,18 @@ func (cli *Client) UserTyping(roomID string, typing bool, timeout int64) (resp *
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cli *Client) SetPresence(status string) (err error) {
|
||||||
|
req := ReqPresence{Presence: status}
|
||||||
|
u := cli.BuildURL("presence", cli.UserID, "status")
|
||||||
|
_, err = cli.MakeRequest("PUT", u, req, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// StateEvent gets a single state event in a room. It will attempt to JSON unmarshal into the given "outContent" struct with
|
// StateEvent gets a single state event in a room. It will attempt to JSON unmarshal into the given "outContent" struct with
|
||||||
// the HTTP response body, or return an error.
|
// the HTTP response body, or return an error.
|
||||||
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype-statekey
|
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype-statekey
|
||||||
func (cli *Client) StateEvent(roomID, eventType, stateKey string, outContent interface{}) (err error) {
|
func (cli *Client) StateEvent(roomID string, eventType EventType, stateKey string, outContent interface{}) (err error) {
|
||||||
u := cli.BuildURL("rooms", roomID, "state", eventType, stateKey)
|
u := cli.BuildURL("rooms", roomID, "state", eventType.String(), stateKey)
|
||||||
_, err = cli.MakeRequest("GET", u, nil, outContent)
|
_, err = cli.MakeRequest("GET", u, nil, outContent)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -587,18 +636,48 @@ func (cli *Client) UploadLink(link string) (*RespMediaUpload, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return cli.UploadToContentRepo(res.Body, res.Header.Get("Content-Type"), res.ContentLength)
|
return cli.Upload(res.Body, res.Header.Get("Content-Type"), res.ContentLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cli *Client) Download(mxcURL string) (io.ReadCloser, error) {
|
||||||
|
if !strings.HasPrefix(mxcURL, "mxc://") {
|
||||||
|
return nil, errors.New("invalid Matrix content URL")
|
||||||
|
}
|
||||||
|
parts := strings.Split(mxcURL[len("mxc://"):], "/")
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return nil, errors.New("invalid Matrix content URL")
|
||||||
|
}
|
||||||
|
u := cli.BuildBaseURL("_matrix/media/r0/download", parts[0], parts[1])
|
||||||
|
resp, err := cli.Client.Get(u)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp.Body, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cli *Client) DownloadBytes(mxcURL string) ([]byte, error) {
|
||||||
|
resp, err := cli.Download(mxcURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Close()
|
||||||
|
return ioutil.ReadAll(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cli *Client) UploadBytes(data []byte, contentType string) (*RespMediaUpload, error) {
|
||||||
|
return cli.Upload(bytes.NewReader(data), contentType, int64(len(data)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// UploadToContentRepo uploads the given bytes to the content repository and returns an MXC URI.
|
// UploadToContentRepo uploads the given bytes to the content repository and returns an MXC URI.
|
||||||
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-media-r0-upload
|
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-media-r0-upload
|
||||||
func (cli *Client) UploadToContentRepo(content io.Reader, contentType string, contentLength int64) (*RespMediaUpload, error) {
|
func (cli *Client) Upload(content io.Reader, contentType string, contentLength int64) (*RespMediaUpload, error) {
|
||||||
req, err := http.NewRequest("POST", cli.BuildBaseURL("_matrix/media/r0/upload"), content)
|
req, err := http.NewRequest("POST", cli.BuildBaseURL("_matrix/media/r0/upload"), content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", contentType)
|
req.Header.Set("Content-Type", contentType)
|
||||||
req.ContentLength = contentLength
|
req.ContentLength = contentLength
|
||||||
|
cli.LogRequest(req, fmt.Sprintf("%d bytes", contentLength))
|
||||||
res, err := cli.Client.Do(req)
|
res, err := cli.Client.Do(req)
|
||||||
if res != nil {
|
if res != nil {
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
@ -666,6 +745,18 @@ func (cli *Client) Messages(roomID, from, to string, dir rune, limit int) (resp
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cli *Client) GetEvent(roomID, eventID string) (resp *Event, err error) {
|
||||||
|
urlPath := cli.BuildURL("rooms", roomID, "event", eventID)
|
||||||
|
_, err = cli.MakeRequest("GET", urlPath, nil, &resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cli *Client) MarkRead(roomID, eventID string) (err error) {
|
||||||
|
urlPath := cli.BuildURL("rooms", roomID, "receipt", "m.read", eventID)
|
||||||
|
_, err = cli.MakeRequest("POST", urlPath, struct{}{}, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// TurnServer returns turn server details and credentials for the client to use when initiating calls.
|
// TurnServer returns turn server details and credentials for the client to use when initiating calls.
|
||||||
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-voip-turnserver
|
// See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-voip-turnserver
|
||||||
func (cli *Client) TurnServer() (resp *RespTurnServer, err error) {
|
func (cli *Client) TurnServer() (resp *RespTurnServer, err error) {
|
||||||
|
465
vendor/maunium.net/go/gomatrix/events.go
generated
vendored
465
vendor/maunium.net/go/gomatrix/events.go
generated
vendored
@ -1,110 +1,413 @@
|
|||||||
package gomatrix
|
package gomatrix
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"html"
|
"encoding/json"
|
||||||
"regexp"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EventTypeClass int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Normal message events
|
||||||
|
MessageEventType EventTypeClass = iota
|
||||||
|
// State events
|
||||||
|
StateEventType
|
||||||
|
// Ephemeral events
|
||||||
|
EphemeralEventType
|
||||||
|
// Account data events
|
||||||
|
AccountDataEventType
|
||||||
|
// Unknown events
|
||||||
|
UnknownEventType
|
||||||
|
)
|
||||||
|
|
||||||
|
type EventType struct {
|
||||||
|
Type string
|
||||||
|
Class EventTypeClass
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEventType(name string) EventType {
|
||||||
|
evtType := EventType{Type: name}
|
||||||
|
evtType.Class = evtType.GuessClass()
|
||||||
|
return evtType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (et *EventType) IsState() bool {
|
||||||
|
return et.Class == StateEventType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (et *EventType) IsEphemeral() bool {
|
||||||
|
return et.Class == EphemeralEventType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (et *EventType) IsCustom() bool {
|
||||||
|
return !strings.HasPrefix(et.Type, "m.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (et *EventType) GuessClass() EventTypeClass {
|
||||||
|
switch et.Type {
|
||||||
|
case StateAliases.Type, StateCanonicalAlias.Type, StateCreate.Type, StateJoinRules.Type, StateMember.Type,
|
||||||
|
StatePowerLevels.Type, StateRoomName.Type, StateRoomAvatar.Type, StateTopic.Type, StatePinnedEvents.Type:
|
||||||
|
return StateEventType
|
||||||
|
case EphemeralEventReceipt.Type, EphemeralEventTyping.Type:
|
||||||
|
return EphemeralEventType
|
||||||
|
case AccountDataDirectChats.Type, AccountDataPushRules.Type, AccountDataRoomTags.Type:
|
||||||
|
return AccountDataEventType
|
||||||
|
case EventRedaction.Type, EventMessage.Type, EventSticker.Type:
|
||||||
|
return MessageEventType
|
||||||
|
default:
|
||||||
|
return UnknownEventType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (et *EventType) UnmarshalJSON(data []byte) error {
|
||||||
|
err := json.Unmarshal(data, &et.Type)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
et.Class = et.GuessClass()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (et *EventType) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(&et.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (et *EventType) String() string {
|
||||||
|
return et.Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// State events
|
||||||
|
var (
|
||||||
|
StateAliases = EventType{"m.room.aliases", StateEventType}
|
||||||
|
StateCanonicalAlias = EventType{"m.room.canonical_alias", StateEventType}
|
||||||
|
StateCreate = EventType{"m.room.create", StateEventType}
|
||||||
|
StateJoinRules = EventType{"m.room.join_rules", StateEventType}
|
||||||
|
StateMember = EventType{"m.room.member", StateEventType}
|
||||||
|
StatePowerLevels = EventType{"m.room.power_levels", StateEventType}
|
||||||
|
StateRoomName = EventType{"m.room.name", StateEventType}
|
||||||
|
StateTopic = EventType{"m.room.topic", StateEventType}
|
||||||
|
StateRoomAvatar = EventType{"m.room.avatar", StateEventType}
|
||||||
|
StatePinnedEvents = EventType{"m.room.pinned_events", StateEventType}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Message events
|
||||||
|
var (
|
||||||
|
EventRedaction = EventType{"m.room.redaction", MessageEventType}
|
||||||
|
EventMessage = EventType{"m.room.message", MessageEventType}
|
||||||
|
EventSticker = EventType{"m.sticker", MessageEventType}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ephemeral events
|
||||||
|
var (
|
||||||
|
EphemeralEventReceipt = EventType{"m.receipt", EphemeralEventType}
|
||||||
|
EphemeralEventTyping = EventType{"m.receipt", EphemeralEventType}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Account data events
|
||||||
|
var (
|
||||||
|
AccountDataDirectChats = EventType{"m.direct", AccountDataEventType}
|
||||||
|
AccountDataPushRules = EventType{"m.push_rules", AccountDataEventType}
|
||||||
|
AccountDataRoomTags = EventType{"m.tag", AccountDataEventType}
|
||||||
|
)
|
||||||
|
|
||||||
|
type MessageType string
|
||||||
|
|
||||||
|
// Msgtypes
|
||||||
|
const (
|
||||||
|
MsgText MessageType = "m.text"
|
||||||
|
MsgEmote = "m.emote"
|
||||||
|
MsgNotice = "m.notice"
|
||||||
|
MsgImage = "m.image"
|
||||||
|
MsgLocation = "m.location"
|
||||||
|
MsgVideo = "m.video"
|
||||||
|
MsgAudio = "m.audio"
|
||||||
|
MsgFile = "m.file"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Format string
|
||||||
|
|
||||||
|
// Message formats
|
||||||
|
const (
|
||||||
|
FormatHTML Format = "org.matrix.custom.html"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Event represents a single Matrix event.
|
// Event represents a single Matrix event.
|
||||||
type Event struct {
|
type Event struct {
|
||||||
StateKey *string `json:"state_key,omitempty"` // The state key for the event. Only present on State Events.
|
StateKey *string `json:"state_key,omitempty"` // The state key for the event. Only present on State Events.
|
||||||
Sender string `json:"sender"` // The user ID of the sender of the event
|
Sender string `json:"sender"` // The user ID of the sender of the event
|
||||||
Type string `json:"type"` // The event type
|
Type EventType `json:"type"` // The event type
|
||||||
Timestamp int64 `json:"origin_server_ts"` // The unix timestamp when this message was sent by the origin server
|
Timestamp int64 `json:"origin_server_ts"` // The unix timestamp when this message was sent by the origin server
|
||||||
ID string `json:"event_id"` // The unique ID of this event
|
ID string `json:"event_id"` // The unique ID of this event
|
||||||
RoomID string `json:"room_id"` // The room the event was sent to. May be nil (e.g. for presence)
|
RoomID string `json:"room_id"` // The room the event was sent to. May be nil (e.g. for presence)
|
||||||
Content map[string]interface{} `json:"content"` // The JSON content of the event.
|
Content Content `json:"content"` // The JSON content of the event.
|
||||||
Redacts string `json:"redacts,omitempty"` // The event ID that was redacted if a m.room.redaction event
|
Redacts string `json:"redacts,omitempty"` // The event ID that was redacted if a m.room.redaction event
|
||||||
Unsigned Unsigned `json:"unsigned,omitempty"` // Unsigned content set by own homeserver.
|
Unsigned Unsigned `json:"unsigned,omitempty"` // Unsigned content set by own homeserver.
|
||||||
|
|
||||||
|
InviteRoomState []StrippedState `json:"invite_room_state"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (evt *Event) GetStateKey() string {
|
||||||
|
if evt.StateKey != nil {
|
||||||
|
return *evt.StateKey
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type StrippedState struct {
|
||||||
|
Content Content `json:"content"`
|
||||||
|
Type EventType `json:"type"`
|
||||||
|
StateKey string `json:"state_key"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Unsigned struct {
|
type Unsigned struct {
|
||||||
PrevContent map[string]interface{} `json:"prev_content,omitempty"`
|
PrevContent *Content `json:"prev_content,omitempty"`
|
||||||
PrevSender string `json:"prev_sender,omitempty"`
|
PrevSender string `json:"prev_sender,omitempty"`
|
||||||
ReplacesState string `json:"replaces_state,omitempty"`
|
ReplacesState string `json:"replaces_state,omitempty"`
|
||||||
Age int64 `json:"age"`
|
Age int64 `json:"age,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Body returns the value of the "body" key in the event content if it is
|
type Content struct {
|
||||||
// present and is a string.
|
VeryRaw json.RawMessage `json:"-"`
|
||||||
func (event *Event) Body() (body string, ok bool) {
|
Raw map[string]interface{} `json:"-"`
|
||||||
value, exists := event.Content["body"]
|
|
||||||
if !exists {
|
MsgType MessageType `json:"msgtype,omitempty"`
|
||||||
return
|
Body string `json:"body,omitempty"`
|
||||||
|
Format Format `json:"format,omitempty"`
|
||||||
|
FormattedBody string `json:"formatted_body,omitempty"`
|
||||||
|
|
||||||
|
Info *FileInfo `json:"info,omitempty"`
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
|
||||||
|
// Membership key for easy access in m.room.member events
|
||||||
|
Membership Membership `json:"membership,omitempty"`
|
||||||
|
|
||||||
|
RelatesTo *RelatesTo `json:"m.relates_to,omitempty"`
|
||||||
|
|
||||||
|
PowerLevels
|
||||||
|
Member
|
||||||
|
Aliases []string `json:"aliases,omitempty"`
|
||||||
|
CanonicalAlias
|
||||||
|
RoomName
|
||||||
|
RoomTopic
|
||||||
|
|
||||||
|
RoomTags Tags `json:"tags,omitempty"`
|
||||||
|
TypingUserIDs []string `json:"user_ids,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type serializableContent Content
|
||||||
|
|
||||||
|
func (content *Content) UnmarshalJSON(data []byte) error {
|
||||||
|
content.VeryRaw = data
|
||||||
|
if err := json.Unmarshal(data, &content.Raw); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
body, ok = value.(string)
|
return json.Unmarshal(data, (*serializableContent)(content))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (content *Content) UnmarshalPowerLevels() (pl PowerLevels, err error) {
|
||||||
|
err = json.Unmarshal(content.VeryRaw, &pl)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageType returns the value of the "msgtype" key in the event content if
|
func (content *Content) UnmarshalMember() (m Member, err error) {
|
||||||
// it is present and is a string.
|
err = json.Unmarshal(content.VeryRaw, &m)
|
||||||
func (event *Event) MessageType() (msgtype string, ok bool) {
|
|
||||||
value, exists := event.Content["msgtype"]
|
|
||||||
if !exists {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
msgtype, ok = value.(string)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TextMessage is the contents of a Matrix formated message event.
|
func (content *Content) UnmarshalCanonicalAlias() (ca CanonicalAlias, err error) {
|
||||||
type TextMessage struct {
|
err = json.Unmarshal(content.VeryRaw, &ca)
|
||||||
MsgType string `json:"msgtype"`
|
return
|
||||||
Body string `json:"body"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageInfo contains info about an image - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-image
|
func (content *Content) GetInfo() *FileInfo {
|
||||||
type ImageInfo struct {
|
if content.Info == nil {
|
||||||
Height uint `json:"h,omitempty"`
|
content.Info = &FileInfo{}
|
||||||
Width uint `json:"w,omitempty"`
|
}
|
||||||
Mimetype string `json:"mimetype,omitempty"`
|
return content.Info
|
||||||
Size uint `json:"size,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VideoInfo contains info about a video - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-video
|
type Tags map[string]struct {
|
||||||
type VideoInfo struct {
|
Order string `json:"order"`
|
||||||
Mimetype string `json:"mimetype,omitempty"`
|
}
|
||||||
ThumbnailInfo ImageInfo `json:"thumbnail_info"`
|
|
||||||
|
type RoomName struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoomTopic struct {
|
||||||
|
Topic string `json:"topic,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Membership is an enum specifying the membership state of a room member.
|
||||||
|
type Membership string
|
||||||
|
|
||||||
|
// The allowed membership states as specified in spec section 10.5.5.
|
||||||
|
const (
|
||||||
|
MembershipJoin Membership = "join"
|
||||||
|
MembershipLeave Membership = "leave"
|
||||||
|
MembershipInvite Membership = "invite"
|
||||||
|
MembershipBan Membership = "ban"
|
||||||
|
MembershipKnock Membership = "knock"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Member struct {
|
||||||
|
Membership Membership `json:"membership,omitempty"`
|
||||||
|
AvatarURL string `json:"avatar_url,omitempty"`
|
||||||
|
Displayname string `json:"displayname,omitempty"`
|
||||||
|
ThirdPartyInvite *ThirdPartyInvite `json:"third_party_invite,omitempty"`
|
||||||
|
Reason string `json:"reason,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ThirdPartyInvite struct {
|
||||||
|
DisplayName string `json:"display_name"`
|
||||||
|
Signed struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
Signatures json.RawMessage `json:"signatures"`
|
||||||
|
MXID string `json:"mxid"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CanonicalAlias struct {
|
||||||
|
Alias string `json:"alias,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PowerLevels struct {
|
||||||
|
usersLock sync.RWMutex `json:"-"`
|
||||||
|
Users map[string]int `json:"users,omitempty"`
|
||||||
|
UsersDefault int `json:"users_default,omitempty"`
|
||||||
|
|
||||||
|
eventsLock sync.RWMutex `json:"-"`
|
||||||
|
Events map[string]int `json:"events,omitempty"`
|
||||||
|
EventsDefault int `json:"events_default,omitempty"`
|
||||||
|
|
||||||
|
StateDefaultPtr *int `json:"state_default,omitempty"`
|
||||||
|
|
||||||
|
InvitePtr *int `json:"invite,omitempty"`
|
||||||
|
KickPtr *int `json:"kick,omitempty"`
|
||||||
|
BanPtr *int `json:"ban,omitempty"`
|
||||||
|
RedactPtr *int `json:"redact,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pl *PowerLevels) Invite() int {
|
||||||
|
if pl.InvitePtr != nil {
|
||||||
|
return *pl.InvitePtr
|
||||||
|
}
|
||||||
|
return 50
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pl *PowerLevels) Kick() int {
|
||||||
|
if pl.KickPtr != nil {
|
||||||
|
return *pl.KickPtr
|
||||||
|
}
|
||||||
|
return 50
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pl *PowerLevels) Ban() int {
|
||||||
|
if pl.BanPtr != nil {
|
||||||
|
return *pl.BanPtr
|
||||||
|
}
|
||||||
|
return 50
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pl *PowerLevels) Redact() int {
|
||||||
|
if pl.RedactPtr != nil {
|
||||||
|
return *pl.RedactPtr
|
||||||
|
}
|
||||||
|
return 50
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pl *PowerLevels) StateDefault() int {
|
||||||
|
if pl.StateDefaultPtr != nil {
|
||||||
|
return *pl.StateDefaultPtr
|
||||||
|
}
|
||||||
|
return 50
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pl *PowerLevels) GetUserLevel(userID string) int {
|
||||||
|
pl.usersLock.RLock()
|
||||||
|
defer pl.usersLock.RUnlock()
|
||||||
|
level, ok := pl.Users[userID]
|
||||||
|
if !ok {
|
||||||
|
return pl.UsersDefault
|
||||||
|
}
|
||||||
|
return level
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pl *PowerLevels) SetUserLevel(userID string, level int) {
|
||||||
|
pl.usersLock.Lock()
|
||||||
|
defer pl.usersLock.Unlock()
|
||||||
|
if level == pl.UsersDefault {
|
||||||
|
delete(pl.Users, userID)
|
||||||
|
} else {
|
||||||
|
pl.Users[userID] = level
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pl *PowerLevels) EnsureUserLevel(userID string, level int) bool {
|
||||||
|
existingLevel := pl.GetUserLevel(userID)
|
||||||
|
if existingLevel != level {
|
||||||
|
pl.SetUserLevel(userID, level)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pl *PowerLevels) GetEventLevel(eventType EventType) int {
|
||||||
|
pl.eventsLock.RLock()
|
||||||
|
defer pl.eventsLock.RUnlock()
|
||||||
|
level, ok := pl.Events[eventType.String()]
|
||||||
|
if !ok {
|
||||||
|
if eventType.IsState() {
|
||||||
|
return pl.StateDefault()
|
||||||
|
}
|
||||||
|
return pl.EventsDefault
|
||||||
|
}
|
||||||
|
return level
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pl *PowerLevels) SetEventLevel(eventType EventType, level int) {
|
||||||
|
pl.eventsLock.Lock()
|
||||||
|
defer pl.eventsLock.Unlock()
|
||||||
|
if (eventType.IsState() && level == pl.StateDefault()) || (!eventType.IsState() && level == pl.EventsDefault) {
|
||||||
|
delete(pl.Events, eventType.String())
|
||||||
|
} else {
|
||||||
|
pl.Events[eventType.String()] = level
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pl *PowerLevels) EnsureEventLevel(eventType EventType, level int) bool {
|
||||||
|
existingLevel := pl.GetEventLevel(eventType)
|
||||||
|
if existingLevel != level {
|
||||||
|
pl.SetEventLevel(eventType, level)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileInfo struct {
|
||||||
|
MimeType string `json:"mimetype,omitempty"`
|
||||||
|
ThumbnailInfo *FileInfo `json:"thumbnail_info,omitempty"`
|
||||||
ThumbnailURL string `json:"thumbnail_url,omitempty"`
|
ThumbnailURL string `json:"thumbnail_url,omitempty"`
|
||||||
Height uint `json:"h,omitempty"`
|
Height int `json:"h,omitempty"`
|
||||||
Width uint `json:"w,omitempty"`
|
Width int `json:"w,omitempty"`
|
||||||
Duration uint `json:"duration,omitempty"`
|
Duration uint `json:"duration,omitempty"`
|
||||||
Size uint `json:"size,omitempty"`
|
Size int `json:"size,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// VideoMessage is an m.video - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-video
|
func (fileInfo *FileInfo) GetThumbnailInfo() *FileInfo {
|
||||||
type VideoMessage struct {
|
if fileInfo.ThumbnailInfo == nil {
|
||||||
MsgType string `json:"msgtype"`
|
fileInfo.ThumbnailInfo = &FileInfo{}
|
||||||
Body string `json:"body"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
Info VideoInfo `json:"info"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ImageMessage is an m.image event
|
|
||||||
type ImageMessage struct {
|
|
||||||
MsgType string `json:"msgtype"`
|
|
||||||
Body string `json:"body"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
Info ImageInfo `json:"info"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// An HTMLMessage is the contents of a Matrix HTML formated message event.
|
|
||||||
type HTMLMessage struct {
|
|
||||||
Body string `json:"body"`
|
|
||||||
MsgType string `json:"msgtype"`
|
|
||||||
Format string `json:"format"`
|
|
||||||
FormattedBody string `json:"formatted_body"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var htmlRegex = regexp.MustCompile("<[^<]+?>")
|
|
||||||
|
|
||||||
// GetHTMLMessage returns an HTMLMessage with the body set to a stripped version of the provided HTML, in addition
|
|
||||||
// to the provided HTML.
|
|
||||||
func GetHTMLMessage(msgtype, htmlText string) HTMLMessage {
|
|
||||||
return HTMLMessage{
|
|
||||||
Body: html.UnescapeString(htmlRegex.ReplaceAllLiteralString(htmlText, "")),
|
|
||||||
MsgType: msgtype,
|
|
||||||
Format: "org.matrix.custom.html",
|
|
||||||
FormattedBody: htmlText,
|
|
||||||
}
|
}
|
||||||
|
return fileInfo.ThumbnailInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type RelatesTo struct {
|
||||||
|
InReplyTo InReplyTo `json:"m.in_reply_to,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InReplyTo struct {
|
||||||
|
EventID string `json:"event_id,omitempty"`
|
||||||
|
// Not required, just for future-proofing
|
||||||
|
RoomID string `json:"room_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
96
vendor/maunium.net/go/gomatrix/reply.go
generated
vendored
Normal file
96
vendor/maunium.net/go/gomatrix/reply.go
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package gomatrix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/net/html"
|
||||||
|
)
|
||||||
|
|
||||||
|
var HTMLReplyFallbackRegex = regexp.MustCompile(`^<mx-reply>[\s\S]+?</mx-reply>`)
|
||||||
|
|
||||||
|
func TrimReplyFallbackHTML(html string) string {
|
||||||
|
return HTMLReplyFallbackRegex.ReplaceAllString(html, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TrimReplyFallbackText(text string) string {
|
||||||
|
if !strings.HasPrefix(text, "> ") || !strings.Contains(text, "\n") {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := strings.Split(text, "\n")
|
||||||
|
for len(lines) > 0 && strings.HasPrefix(lines[0], "> ") {
|
||||||
|
lines = lines[1:]
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(strings.Join(lines, "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (content *Content) RemoveReplyFallback() {
|
||||||
|
if len(content.GetReplyTo()) > 0 {
|
||||||
|
if content.Format == FormatHTML {
|
||||||
|
content.FormattedBody = TrimReplyFallbackHTML(content.FormattedBody)
|
||||||
|
}
|
||||||
|
content.Body = TrimReplyFallbackText(content.Body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (content *Content) GetReplyTo() string {
|
||||||
|
if content.RelatesTo != nil {
|
||||||
|
return content.RelatesTo.InReplyTo.EventID
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReplyFormat = `<mx-reply><blockquote>
|
||||||
|
<a href="https://matrix.to/#/%s/%s">In reply to</a>
|
||||||
|
<a href="https://matrix.to/#/%s">%s</a>
|
||||||
|
%s
|
||||||
|
</blockquote></mx-reply>
|
||||||
|
`
|
||||||
|
|
||||||
|
func (evt *Event) GenerateReplyFallbackHTML() string {
|
||||||
|
body := evt.Content.FormattedBody
|
||||||
|
if len(body) == 0 {
|
||||||
|
body = html.EscapeString(evt.Content.Body)
|
||||||
|
}
|
||||||
|
|
||||||
|
senderDisplayName := evt.Sender
|
||||||
|
|
||||||
|
return fmt.Sprintf(ReplyFormat, evt.RoomID, evt.ID, evt.Sender, senderDisplayName, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (evt *Event) GenerateReplyFallbackText() string {
|
||||||
|
body := evt.Content.Body
|
||||||
|
lines := strings.Split(strings.TrimSpace(body), "\n")
|
||||||
|
firstLine, lines := lines[0], lines[1:]
|
||||||
|
|
||||||
|
senderDisplayName := evt.Sender
|
||||||
|
|
||||||
|
var fallbackText strings.Builder
|
||||||
|
fmt.Fprintf(&fallbackText, "> <%s> %s", senderDisplayName, firstLine)
|
||||||
|
for _, line := range lines {
|
||||||
|
fmt.Fprintf(&fallbackText, "\n> %s", line)
|
||||||
|
}
|
||||||
|
fallbackText.WriteString("\n\n")
|
||||||
|
return fallbackText.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (content *Content) SetReply(inReplyTo *Event) {
|
||||||
|
if content.RelatesTo == nil {
|
||||||
|
content.RelatesTo = &RelatesTo{}
|
||||||
|
}
|
||||||
|
content.RelatesTo.InReplyTo = InReplyTo{
|
||||||
|
EventID: inReplyTo.ID,
|
||||||
|
RoomID: inReplyTo.RoomID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if content.MsgType == MsgText || content.MsgType == MsgNotice {
|
||||||
|
if len(content.FormattedBody) == 0 || content.Format != FormatHTML {
|
||||||
|
content.FormattedBody = html.EscapeString(content.Body)
|
||||||
|
content.Format = FormatHTML
|
||||||
|
}
|
||||||
|
content.FormattedBody = inReplyTo.GenerateReplyFallbackHTML() + content.FormattedBody
|
||||||
|
content.Body = inReplyTo.GenerateReplyFallbackText() + content.Body
|
||||||
|
}
|
||||||
|
}
|
8
vendor/maunium.net/go/gomatrix/requests.go
generated
vendored
8
vendor/maunium.net/go/gomatrix/requests.go
generated
vendored
@ -31,7 +31,7 @@ type ReqCreateRoom struct {
|
|||||||
Invite []string `json:"invite,omitempty"`
|
Invite []string `json:"invite,omitempty"`
|
||||||
Invite3PID []ReqInvite3PID `json:"invite_3pid,omitempty"`
|
Invite3PID []ReqInvite3PID `json:"invite_3pid,omitempty"`
|
||||||
CreationContent map[string]interface{} `json:"creation_content,omitempty"`
|
CreationContent map[string]interface{} `json:"creation_content,omitempty"`
|
||||||
InitialState []Event `json:"initial_state,omitempty"`
|
InitialState []*Event `json:"initial_state,omitempty"`
|
||||||
Preset string `json:"preset,omitempty"`
|
Preset string `json:"preset,omitempty"`
|
||||||
IsDirect bool `json:"is_direct,omitempty"`
|
IsDirect bool `json:"is_direct,omitempty"`
|
||||||
}
|
}
|
||||||
@ -74,5 +74,9 @@ type ReqUnbanUser struct {
|
|||||||
// ReqTyping is the JSON request for https://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-typing-userid
|
// ReqTyping is the JSON request for https://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-typing-userid
|
||||||
type ReqTyping struct {
|
type ReqTyping struct {
|
||||||
Typing bool `json:"typing"`
|
Typing bool `json:"typing"`
|
||||||
Timeout int64 `json:"timeout"`
|
Timeout int64 `json:"timeout,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ReqPresence struct {
|
||||||
|
Presence string `json:"presence"`
|
||||||
|
}
|
2
vendor/maunium.net/go/gomatrix/responses.go
generated
vendored
2
vendor/maunium.net/go/gomatrix/responses.go
generated
vendored
@ -64,7 +64,7 @@ type RespJoinedMembers struct {
|
|||||||
// RespMessages is the JSON response for https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-messages
|
// RespMessages is the JSON response for https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-messages
|
||||||
type RespMessages struct {
|
type RespMessages struct {
|
||||||
Start string `json:"start"`
|
Start string `json:"start"`
|
||||||
Chunk []Event `json:"chunk"`
|
Chunk []*Event `json:"chunk"`
|
||||||
End string `json:"end"`
|
End string `json:"end"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
vendor/maunium.net/go/gomatrix/room.go
generated
vendored
20
vendor/maunium.net/go/gomatrix/room.go
generated
vendored
@ -3,7 +3,7 @@ package gomatrix
|
|||||||
// Room represents a single Matrix room.
|
// Room represents a single Matrix room.
|
||||||
type Room struct {
|
type Room struct {
|
||||||
ID string
|
ID string
|
||||||
State map[string]map[string]*Event
|
State map[EventType]map[string]*Event
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateState updates the room's current state with the given Event. This will clobber events based
|
// UpdateState updates the room's current state with the given Event. This will clobber events based
|
||||||
@ -17,7 +17,7 @@ func (room Room) UpdateState(event *Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetStateEvent returns the state event for the given type/state_key combo, or nil.
|
// GetStateEvent returns the state event for the given type/state_key combo, or nil.
|
||||||
func (room Room) GetStateEvent(eventType string, stateKey string) *Event {
|
func (room Room) GetStateEvent(eventType EventType, stateKey string) *Event {
|
||||||
stateEventMap, _ := room.State[eventType]
|
stateEventMap, _ := room.State[eventType]
|
||||||
event, _ := stateEventMap[stateKey]
|
event, _ := stateEventMap[stateKey]
|
||||||
return event
|
return event
|
||||||
@ -25,17 +25,11 @@ func (room Room) GetStateEvent(eventType string, stateKey string) *Event {
|
|||||||
|
|
||||||
// GetMembershipState returns the membership state of the given user ID in this room. If there is
|
// GetMembershipState returns the membership state of the given user ID in this room. If there is
|
||||||
// no entry for this member, 'leave' is returned for consistency with left users.
|
// no entry for this member, 'leave' is returned for consistency with left users.
|
||||||
func (room Room) GetMembershipState(userID string) string {
|
func (room Room) GetMembershipState(userID string) Membership {
|
||||||
state := "leave"
|
state := MembershipLeave
|
||||||
event := room.GetStateEvent("m.room.member", userID)
|
event := room.GetStateEvent(StateMember, userID)
|
||||||
if event != nil {
|
if event != nil {
|
||||||
membershipState, found := event.Content["membership"]
|
state = event.Content.Membership
|
||||||
if found {
|
|
||||||
mState, isString := membershipState.(string)
|
|
||||||
if isString {
|
|
||||||
state = mState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
@ -45,6 +39,6 @@ func NewRoom(roomID string) *Room {
|
|||||||
// Init the State map and return a pointer to the Room
|
// Init the State map and return a pointer to the Room
|
||||||
return &Room{
|
return &Room{
|
||||||
ID: roomID,
|
ID: roomID,
|
||||||
State: make(map[string]map[string]*Event),
|
State: make(map[EventType]map[string]*Event),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
vendor/maunium.net/go/gomatrix/sync.go
generated
vendored
15
vendor/maunium.net/go/gomatrix/sync.go
generated
vendored
@ -25,7 +25,7 @@ type Syncer interface {
|
|||||||
type DefaultSyncer struct {
|
type DefaultSyncer struct {
|
||||||
UserID string
|
UserID string
|
||||||
Store Storer
|
Store Storer
|
||||||
listeners map[string][]OnEventListener // event type to listeners array
|
listeners map[EventType][]OnEventListener // event type to listeners array
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnEventListener can be used with DefaultSyncer.OnEventType to be informed of incoming events.
|
// OnEventListener can be used with DefaultSyncer.OnEventType to be informed of incoming events.
|
||||||
@ -36,7 +36,7 @@ func NewDefaultSyncer(userID string, store Storer) *DefaultSyncer {
|
|||||||
return &DefaultSyncer{
|
return &DefaultSyncer{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
Store: store,
|
Store: store,
|
||||||
listeners: make(map[string][]OnEventListener),
|
listeners: make(map[EventType][]OnEventListener),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ func (s *DefaultSyncer) ProcessResponse(res *RespSync, since string) (err error)
|
|||||||
|
|
||||||
// OnEventType allows callers to be notified when there are new events for the given event type.
|
// OnEventType allows callers to be notified when there are new events for the given event type.
|
||||||
// There are no duplicate checks.
|
// There are no duplicate checks.
|
||||||
func (s *DefaultSyncer) OnEventType(eventType string, callback OnEventListener) {
|
func (s *DefaultSyncer) OnEventType(eventType EventType, callback OnEventListener) {
|
||||||
_, exists := s.listeners[eventType]
|
_, exists := s.listeners[eventType]
|
||||||
if !exists {
|
if !exists {
|
||||||
s.listeners[eventType] = []OnEventListener{}
|
s.listeners[eventType] = []OnEventListener{}
|
||||||
@ -112,13 +112,8 @@ func (s *DefaultSyncer) shouldProcessResponse(resp *RespSync, since string) bool
|
|||||||
for roomID, roomData := range resp.Rooms.Join {
|
for roomID, roomData := range resp.Rooms.Join {
|
||||||
for i := len(roomData.Timeline.Events) - 1; i >= 0; i-- {
|
for i := len(roomData.Timeline.Events) - 1; i >= 0; i-- {
|
||||||
e := roomData.Timeline.Events[i]
|
e := roomData.Timeline.Events[i]
|
||||||
if e.Type == "m.room.member" && e.StateKey != nil && *e.StateKey == s.UserID {
|
if e.Type == StateMember && e.GetStateKey() == s.UserID {
|
||||||
m := e.Content["membership"]
|
if e.Content.Membership == "join" {
|
||||||
mship, ok := m.(string)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if mship == "join" {
|
|
||||||
_, ok := resp.Rooms.Join[roomID]
|
_, ok := resp.Rooms.Join[roomID]
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
|
21
vendor/maunium.net/go/maulogger/LICENSE
generated
vendored
Normal file
21
vendor/maunium.net/go/maulogger/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Tulir Asokan
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
6
vendor/maunium.net/go/maulogger/README.md
generated
vendored
Normal file
6
vendor/maunium.net/go/maulogger/README.md
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# maulogger
|
||||||
|
A logger in Go.
|
||||||
|
|
||||||
|
Docs: [godoc.org/maunium.net/go/maulogger](https://godoc.org/maunium.net/go/maulogger)
|
||||||
|
|
||||||
|
Go get: `go get maunium.net/go/maulogger`
|
219
vendor/maunium.net/go/maulogger/logger.go
generated
vendored
Normal file
219
vendor/maunium.net/go/maulogger/logger.go
generated
vendored
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
package maulog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Level is the severity level of a log entry.
|
||||||
|
type Level struct {
|
||||||
|
Name string
|
||||||
|
Severity, Color int
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogWriter writes to the log with an optional prefix
|
||||||
|
type LogWriter struct {
|
||||||
|
Level Level
|
||||||
|
Prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lw LogWriter) Write(p []byte) (n int, err error) {
|
||||||
|
log(lw.Level, fmt.Sprint(lw.Prefix, string(p)))
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetColor gets the ANSI escape color code for the log level.
|
||||||
|
func (lvl Level) GetColor() []byte {
|
||||||
|
if lvl.Color < 0 {
|
||||||
|
return []byte("")
|
||||||
|
}
|
||||||
|
return []byte(fmt.Sprintf("\x1b[%dm", lvl.Color))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReset gets the ANSI escape reset code.
|
||||||
|
func (lvl Level) GetReset() []byte {
|
||||||
|
if lvl.Color < 0 {
|
||||||
|
return []byte("")
|
||||||
|
}
|
||||||
|
return []byte("\x1b[0m")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Debug is the level for debug messages.
|
||||||
|
Debug = Level{Name: "DEBUG", Color: 36, Severity: 0}
|
||||||
|
// Info is the level for basic log messages.
|
||||||
|
Info = Level{Name: "INFO", Color: -1, Severity: 10}
|
||||||
|
// Warn is the level saying that something went wrong, but the program will continue operating mostly normally.
|
||||||
|
Warn = Level{Name: "WARN", Color: 33, Severity: 50}
|
||||||
|
// Error is the level saying that something went wrong and the program may not operate as expected, but will still continue.
|
||||||
|
Error = Level{Name: "ERROR", Color: 31, Severity: 100}
|
||||||
|
// Fatal is the level saying that something went wrong and the program will not operate normally.
|
||||||
|
Fatal = Level{Name: "FATAL", Color: 35, Severity: 9001}
|
||||||
|
)
|
||||||
|
|
||||||
|
// PrintLevel tells the first severity level at which messages should be printed to stdout
|
||||||
|
var PrintLevel = 10
|
||||||
|
|
||||||
|
// PrintDebug means PrintLevel = 0, kept for backwards compatibility
|
||||||
|
var PrintDebug = false
|
||||||
|
|
||||||
|
// FileTimeformat is the time format used in log file names.
|
||||||
|
var FileTimeformat = "2006-01-02"
|
||||||
|
|
||||||
|
// FileformatArgs is an undocumented integer.
|
||||||
|
var FileformatArgs = 3
|
||||||
|
|
||||||
|
// Fileformat is the format used for log file names.
|
||||||
|
var Fileformat = func(now string, i int) string { return fmt.Sprintf("%[1]s-%02[2]d.log", now, i) }
|
||||||
|
|
||||||
|
// Timeformat is the time format used in logging.
|
||||||
|
var Timeformat = "15:04:05 02.01.2006"
|
||||||
|
|
||||||
|
var writer *bufio.Writer
|
||||||
|
var lines int
|
||||||
|
|
||||||
|
// InitWithWriter initializes MauLogger with the given writer.
|
||||||
|
func InitWithWriter(w *bufio.Writer) {
|
||||||
|
writer = w
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init initializes MauLogger.
|
||||||
|
func Init() {
|
||||||
|
// Find the next file name.
|
||||||
|
now := time.Now().Format(FileTimeformat)
|
||||||
|
i := 1
|
||||||
|
for ; ; i++ {
|
||||||
|
if _, err := os.Stat(Fileformat(now, i)); os.IsNotExist(err) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if i == 99 {
|
||||||
|
i = 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Open the file
|
||||||
|
file, err := os.OpenFile(Fileformat(now, i), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0700)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if file == nil {
|
||||||
|
panic(os.ErrInvalid)
|
||||||
|
}
|
||||||
|
// Create a writer
|
||||||
|
writer = bufio.NewWriter(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debugf formats and logs a debug message.
|
||||||
|
func Debugf(message string, args ...interface{}) {
|
||||||
|
logln(Debug, fmt.Sprintf(message, args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printf formats and logs a string in the Info log level.
|
||||||
|
func Printf(message string, args ...interface{}) {
|
||||||
|
Infof(message, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Infof formats and logs a string in the Info log level.
|
||||||
|
func Infof(message string, args ...interface{}) {
|
||||||
|
logln(Info, fmt.Sprintf(message, args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warnf formats and logs a string in the Warn log level.
|
||||||
|
func Warnf(message string, args ...interface{}) {
|
||||||
|
logln(Warn, fmt.Sprintf(message, args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Errorf formats and logs a string in the Error log level.
|
||||||
|
func Errorf(message string, args ...interface{}) {
|
||||||
|
logln(Error, fmt.Sprintf(message, args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fatalf formats and logs a string in the Fatal log level.
|
||||||
|
func Fatalf(message string, args ...interface{}) {
|
||||||
|
logln(Fatal, fmt.Sprintf(message, args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logf formats and logs a message in the given log level.
|
||||||
|
func Logf(level Level, message string, args ...interface{}) {
|
||||||
|
logln(level, fmt.Sprintf(message, args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debugln logs a debug message.
|
||||||
|
func Debugln(args ...interface{}) {
|
||||||
|
log(Debug, fmt.Sprintln(args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Println logs a string in the Info log level.
|
||||||
|
func Println(args ...interface{}) {
|
||||||
|
Infoln(args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Infoln logs a string in the Info log level.
|
||||||
|
func Infoln(args ...interface{}) {
|
||||||
|
log(Info, fmt.Sprintln(args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warnln logs a string in the Warn log level.
|
||||||
|
func Warnln(args ...interface{}) {
|
||||||
|
log(Warn, fmt.Sprintln(args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Errorln logs a string in the Error log level.
|
||||||
|
func Errorln(args ...interface{}) {
|
||||||
|
log(Error, fmt.Sprintln(args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fatalln logs a string in the Fatal log level.
|
||||||
|
func Fatalln(args ...interface{}) {
|
||||||
|
log(Fatal, fmt.Sprintln(args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logln logs a message in the given log level.
|
||||||
|
func Logln(level Level, args ...interface{}) {
|
||||||
|
log(level, fmt.Sprintln(args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func logln(level Level, message string) {
|
||||||
|
log(level, fmt.Sprintln(message))
|
||||||
|
}
|
||||||
|
|
||||||
|
func log(level Level, message string) {
|
||||||
|
// Prefix the message with the timestamp and log level.
|
||||||
|
msg := []byte(fmt.Sprintf("[%[1]s] [%[2]s] %[3]s", time.Now().Format(Timeformat), level.Name, message))
|
||||||
|
|
||||||
|
if writer != nil {
|
||||||
|
// Write it to the log file.
|
||||||
|
_, err := writer.Write(msg)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
lines++
|
||||||
|
// Flush the file if needed
|
||||||
|
if lines == 5 {
|
||||||
|
lines = 0
|
||||||
|
writer.Flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print to stdout using correct color
|
||||||
|
if level.Severity >= PrintLevel || PrintDebug {
|
||||||
|
if level.Severity >= Error.Severity {
|
||||||
|
os.Stderr.Write(level.GetColor())
|
||||||
|
os.Stderr.Write(msg)
|
||||||
|
os.Stderr.Write(level.GetReset())
|
||||||
|
} else {
|
||||||
|
os.Stdout.Write(level.GetColor())
|
||||||
|
os.Stdout.Write(msg)
|
||||||
|
os.Stdout.Write(level.GetReset())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shutdown cleans up the logger.
|
||||||
|
func Shutdown() {
|
||||||
|
if writer != nil {
|
||||||
|
writer.Flush()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user