bug: use deditated type for all TimelineItem

This commit is contained in:
Michael Muré 2018-09-30 17:15:54 +02:00
parent d71bb7dd76
commit 7f86898ef9
No known key found for this signature in database
GPG Key ID: A4457C029293126F
16 changed files with 1240 additions and 457 deletions

View File

@ -42,7 +42,11 @@ func (op *AddCommentOperation) Apply(snapshot *Snapshot) {
panic(err)
}
snapshot.Timeline = append(snapshot.Timeline, NewCommentTimelineItem(hash, comment))
item := &AddCommentTimelineItem{
CommentTimelineItem: NewCommentTimelineItem(hash, comment),
}
snapshot.Timeline = append(snapshot.Timeline, item)
}
func (op *AddCommentOperation) GetFiles() []git.Hash {
@ -73,6 +77,11 @@ func NewAddCommentOp(author Person, unixTime int64, message string, files []git.
}
}
// CreateTimelineItem replace a AddComment operation in the Timeline and hold its edition history
type AddCommentTimelineItem struct {
CommentTimelineItem
}
// Convenience function to apply the operation
func AddComment(b Interface, author Person, unixTime int64, message string) error {
return AddCommentWithFiles(b, author, unixTime, message, nil)

View File

@ -47,7 +47,9 @@ func (op *CreateOperation) Apply(snapshot *Snapshot) {
}
snapshot.Timeline = []TimelineItem{
NewCreateTimelineItem(hash, comment),
&CreateTimelineItem{
CommentTimelineItem: NewCommentTimelineItem(hash, comment),
},
}
}
@ -88,6 +90,11 @@ func NewCreateOp(author Person, unixTime int64, title, message string, files []g
}
}
// CreateTimelineItem replace a Create operation in the Timeline and hold its edition history
type CreateTimelineItem struct {
CommentTimelineItem
}
// Convenience function to apply the operation
func Create(author Person, unixTime int64, title, message string) (*Bug, error) {
return CreateWithFiles(author, unixTime, title, message, nil)

View File

@ -36,7 +36,9 @@ func TestCreate(t *testing.T) {
Author: rene,
CreatedAt: create.Time(),
Timeline: []TimelineItem{
NewCreateTimelineItem(hash, comment),
&CreateTimelineItem{
CommentTimelineItem: NewCommentTimelineItem(hash, comment),
},
},
}

View File

@ -33,12 +33,7 @@ func (op *EditCommentOperation) Apply(snapshot *Snapshot) {
var commentIndex int
for i, item := range snapshot.Timeline {
h, err := item.Hash()
if err != nil {
// Should never happen, we control what goes into the timeline
panic(err)
}
h := item.Hash()
if h == op.Target {
target = snapshot.Timeline[i]
@ -68,8 +63,8 @@ func (op *EditCommentOperation) Apply(snapshot *Snapshot) {
item := target.(*CreateTimelineItem)
item.Append(comment)
case *CommentTimelineItem:
item := target.(*CommentTimelineItem)
case *AddCommentTimelineItem:
item := target.(*AddCommentTimelineItem)
item.Append(comment)
}

View File

@ -38,7 +38,7 @@ func TestEdit(t *testing.T) {
assert.Equal(t, len(snapshot.Timeline), 2)
assert.Equal(t, len(snapshot.Timeline[0].(*CreateTimelineItem).History), 2)
assert.Equal(t, len(snapshot.Timeline[1].(*CommentTimelineItem).History), 1)
assert.Equal(t, len(snapshot.Timeline[1].(*AddCommentTimelineItem).History), 1)
assert.Equal(t, snapshot.Comments[0].Message, "create edited")
assert.Equal(t, snapshot.Comments[1].Message, "comment")
@ -47,7 +47,7 @@ func TestEdit(t *testing.T) {
assert.Equal(t, len(snapshot.Timeline), 2)
assert.Equal(t, len(snapshot.Timeline[0].(*CreateTimelineItem).History), 2)
assert.Equal(t, len(snapshot.Timeline[1].(*CommentTimelineItem).History), 2)
assert.Equal(t, len(snapshot.Timeline[1].(*AddCommentTimelineItem).History), 2)
assert.Equal(t, snapshot.Comments[0].Message, "create edited")
assert.Equal(t, snapshot.Comments[1].Message, "comment edited")
}

View File

@ -55,7 +55,22 @@ AddLoop:
return string(snapshot.Labels[i]) < string(snapshot.Labels[j])
})
snapshot.Timeline = append(snapshot.Timeline, op)
hash, err := op.Hash()
if err != nil {
// Should never error unless a programming error happened
// (covered in OpBase.Validate())
panic(err)
}
item := &LabelChangeTimelineItem{
hash: hash,
Author: op.Author,
UnixTime: Timestamp(op.UnixTime),
Added: op.Added,
Removed: op.Removed,
}
snapshot.Timeline = append(snapshot.Timeline, item)
}
func (op *LabelChangeOperation) Validate() error {
@ -90,6 +105,18 @@ func NewLabelChangeOperation(author Person, unixTime int64, added, removed []Lab
}
}
type LabelChangeTimelineItem struct {
hash git.Hash
Author Person
UnixTime Timestamp
Added []Label
Removed []Label
}
func (l LabelChangeTimelineItem) Hash() git.Hash {
return l.hash
}
// ChangeLabels is a convenience function to apply the operation
func ChangeLabels(b Interface, author Person, unixTime int64, add, remove []string) ([]LabelChangeResult, error) {
var added, removed []Label

View File

@ -23,7 +23,22 @@ func (op *SetStatusOperation) Hash() (git.Hash, error) {
func (op *SetStatusOperation) Apply(snapshot *Snapshot) {
snapshot.Status = op.Status
snapshot.Timeline = append(snapshot.Timeline, op)
hash, err := op.Hash()
if err != nil {
// Should never error unless a programming error happened
// (covered in OpBase.Validate())
panic(err)
}
item := &SetStatusTimelineItem{
hash: hash,
Author: op.Author,
UnixTime: Timestamp(op.UnixTime),
Status: op.Status,
}
snapshot.Timeline = append(snapshot.Timeline, item)
}
func (op *SetStatusOperation) Validate() error {
@ -45,6 +60,17 @@ func NewSetStatusOp(author Person, unixTime int64, status Status) *SetStatusOper
}
}
type SetStatusTimelineItem struct {
hash git.Hash
Author Person
UnixTime Timestamp
Status Status
}
func (s SetStatusTimelineItem) Hash() git.Hash {
return s.hash
}
// Convenience function to apply the operation
func Open(b Interface, author Person, unixTime int64) error {
op := NewSetStatusOp(author, unixTime, OpenStatus)

View File

@ -27,7 +27,23 @@ func (op *SetTitleOperation) Hash() (git.Hash, error) {
func (op *SetTitleOperation) Apply(snapshot *Snapshot) {
snapshot.Title = op.Title
snapshot.Timeline = append(snapshot.Timeline, op)
hash, err := op.Hash()
if err != nil {
// Should never error unless a programming error happened
// (covered in OpBase.Validate())
panic(err)
}
item := &SetTitleTimelineItem{
hash: hash,
Author: op.Author,
UnixTime: Timestamp(op.UnixTime),
Title: op.Title,
Was: op.Was,
}
snapshot.Timeline = append(snapshot.Timeline, item)
}
func (op *SetTitleOperation) Validate() error {
@ -66,6 +82,18 @@ func NewSetTitleOp(author Person, unixTime int64, title string, was string) *Set
}
}
type SetTitleTimelineItem struct {
hash git.Hash
Author Person
UnixTime Timestamp
Title string
Was string
}
func (s SetTitleTimelineItem) Hash() git.Hash {
return s.hash
}
// Convenience function to apply the operation
func SetTitle(b Interface, author Person, unixTime int64, title string) error {
it := NewOperationIterator(b)

View File

@ -61,12 +61,7 @@ func (snap *Snapshot) LastEditUnix() int64 {
// SearchTimelineItem will search in the timeline for an item matching the given hash
func (snap *Snapshot) SearchTimelineItem(hash git.Hash) (TimelineItem, error) {
for i := range snap.Timeline {
h, err := snap.Timeline[i].Hash()
if err != nil {
return nil, err
}
if h == hash {
if snap.Timeline[i].Hash() == hash {
return snap.Timeline[i], nil
}
}

View File

@ -6,7 +6,7 @@ import (
type TimelineItem interface {
// Hash return the hash of the item
Hash() (git.Hash, error)
Hash() git.Hash
}
type CommentHistoryStep struct {
@ -14,31 +14,7 @@ type CommentHistoryStep struct {
UnixTime Timestamp
}
// CreateTimelineItem replace a Create operation in the Timeline and hold its edition history
type CreateTimelineItem struct {
CommentTimelineItem
}
func NewCreateTimelineItem(hash git.Hash, comment Comment) *CreateTimelineItem {
return &CreateTimelineItem{
CommentTimelineItem: CommentTimelineItem{
hash: hash,
Author: comment.Author,
Message: comment.Message,
Files: comment.Files,
CreatedAt: comment.UnixTime,
LastEdit: comment.UnixTime,
History: []CommentHistoryStep{
{
Message: comment.Message,
UnixTime: comment.UnixTime,
},
},
},
}
}
// CommentTimelineItem replace a Comment in the Timeline and hold its edition history
// CommentTimelineItem is a TimelineItem that holds a Comment and its edition history
type CommentTimelineItem struct {
hash git.Hash
Author Person
@ -49,8 +25,8 @@ type CommentTimelineItem struct {
History []CommentHistoryStep
}
func NewCommentTimelineItem(hash git.Hash, comment Comment) *CommentTimelineItem {
return &CommentTimelineItem{
func NewCommentTimelineItem(hash git.Hash, comment Comment) CommentTimelineItem {
return CommentTimelineItem{
hash: hash,
Author: comment.Author,
Message: comment.Message,
@ -66,8 +42,8 @@ func NewCommentTimelineItem(hash git.Hash, comment Comment) *CommentTimelineItem
}
}
func (c *CommentTimelineItem) Hash() (git.Hash, error) {
return c.hash, nil
func (c *CommentTimelineItem) Hash() git.Hash {
return c.hash
}
// Append will append a new comment in the history and update the other values

View File

@ -37,5 +37,11 @@ models:
model: github.com/MichaelMure/git-bug/bug.CommentHistoryStep
CreateTimelineItem:
model: github.com/MichaelMure/git-bug/bug.CreateTimelineItem
CommentTimelineItem:
model: github.com/MichaelMure/git-bug/bug.CommentTimelineItem
AddCommentTimelineItem:
model: github.com/MichaelMure/git-bug/bug.AddCommentTimelineItem
LabelChangeTimelineItem:
model: github.com/MichaelMure/git-bug/bug.LabelChangeTimelineItem
SetStatusTimelineItem:
model: github.com/MichaelMure/git-bug/bug.SetStatusTimelineItem
SetTitleTimelineItem:
model: github.com/MichaelMure/git-bug/bug.SetTitleTimelineItem

File diff suppressed because it is too large Load Diff

View File

@ -40,14 +40,26 @@ func (RootResolver) CommentHistoryStep() graph.CommentHistoryStepResolver {
return &commentHistoryStepResolver{}
}
func (RootResolver) CommentTimelineItem() graph.CommentTimelineItemResolver {
return &commentTimelineItemResolver{}
func (RootResolver) AddCommentTimelineItem() graph.AddCommentTimelineItemResolver {
return &addCommentTimelineItemResolver{}
}
func (RootResolver) CreateTimelineItem() graph.CreateTimelineItemResolver {
return &createTimelineItemResolver{}
}
func (r RootResolver) LabelChangeTimelineItem() graph.LabelChangeTimelineItemResolver {
return &labelChangeTimelineItem{}
}
func (r RootResolver) SetStatusTimelineItem() graph.SetStatusTimelineItemResolver {
return &setStatusTimelineItem{}
}
func (r RootResolver) SetTitleTimelineItem() graph.SetTitleTimelineItemResolver {
return &setTitleTimelineItem{}
}
func (RootResolver) CreateOperation() graph.CreateOperationResolver {
return &createOperationResolver{}
}

View File

@ -5,6 +5,7 @@ import (
"time"
"github.com/MichaelMure/git-bug/bug"
"github.com/MichaelMure/git-bug/graphql/models"
)
type commentHistoryStepResolver struct{}
@ -13,13 +14,13 @@ func (commentHistoryStepResolver) Date(ctx context.Context, obj *bug.CommentHist
return obj.UnixTime.Time(), nil
}
type commentTimelineItemResolver struct{}
type addCommentTimelineItemResolver struct{}
func (commentTimelineItemResolver) CreatedAt(ctx context.Context, obj *bug.CommentTimelineItem) (time.Time, error) {
func (addCommentTimelineItemResolver) CreatedAt(ctx context.Context, obj *bug.AddCommentTimelineItem) (time.Time, error) {
return obj.CreatedAt.Time(), nil
}
func (commentTimelineItemResolver) LastEdit(ctx context.Context, obj *bug.CommentTimelineItem) (time.Time, error) {
func (addCommentTimelineItemResolver) LastEdit(ctx context.Context, obj *bug.AddCommentTimelineItem) (time.Time, error) {
return obj.LastEdit.Time(), nil
}
@ -27,10 +28,30 @@ type createTimelineItemResolver struct{}
func (createTimelineItemResolver) CreatedAt(ctx context.Context, obj *bug.CreateTimelineItem) (time.Time, error) {
return obj.CreatedAt.Time(), nil
}
func (createTimelineItemResolver) LastEdit(ctx context.Context, obj *bug.CreateTimelineItem) (time.Time, error) {
return obj.LastEdit.Time(), nil
}
type labelChangeTimelineItem struct{}
func (labelChangeTimelineItem) Date(ctx context.Context, obj *bug.LabelChangeTimelineItem) (time.Time, error) {
return obj.UnixTime.Time(), nil
}
type setStatusTimelineItem struct{}
func (setStatusTimelineItem) Date(ctx context.Context, obj *bug.SetStatusTimelineItem) (time.Time, error) {
return obj.UnixTime.Time(), nil
}
func (setStatusTimelineItem) Status(ctx context.Context, obj *bug.SetStatusTimelineItem) (models.Status, error) {
return convertStatus(obj.Status)
}
type setTitleTimelineItem struct{}
func (setTitleTimelineItem) Date(ctx context.Context, obj *bug.SetTitleTimelineItem) (time.Time, error) {
return obj.UnixTime.Time(), nil
}

View File

@ -95,7 +95,7 @@ type CreateOperation implements Operation & Authored {
files: [Hash!]!
}
type SetTitleOperation implements Operation & Authored & TimelineItem {
type SetTitleOperation implements Operation & Authored {
hash: Hash!
author: Person!
date: Time!
@ -112,7 +112,7 @@ type AddCommentOperation implements Operation & Authored {
files: [Hash!]!
}
type SetStatusOperation implements Operation & Authored & TimelineItem {
type SetStatusOperation implements Operation & Authored {
hash: Hash!
author: Person!
date: Time!
@ -120,7 +120,7 @@ type SetStatusOperation implements Operation & Authored & TimelineItem {
status: Status!
}
type LabelChangeOperation implements Operation & Authored & TimelineItem {
type LabelChangeOperation implements Operation & Authored {
hash: Hash!
author: Person!
date: Time!
@ -157,7 +157,7 @@ type CreateTimelineItem implements TimelineItem {
history: [CommentHistoryStep!]!
}
type CommentTimelineItem implements TimelineItem {
type AddCommentTimelineItem implements TimelineItem {
hash: Hash!
author: Person!
message: String!
@ -168,6 +168,29 @@ type CommentTimelineItem implements TimelineItem {
history: [CommentHistoryStep!]!
}
type LabelChangeTimelineItem implements TimelineItem {
hash: Hash!
author: Person!
date: Time!
added: [Label!]!
removed: [Label!]!
}
type SetStatusTimelineItem implements TimelineItem {
hash: Hash!
author: Person!
date: Time!
status: Status!
}
type SetTitleTimelineItem implements TimelineItem {
hash: Hash!
author: Person!
date: Time!
title: String!
was: String!
}
"""The connection type for Bug."""
type BugConnection {
"""A list of edges."""

View File

@ -253,8 +253,8 @@ func (sb *showBug) renderMain(g *gocui.Gui, mainView *gocui.View) error {
fmt.Fprint(v, content)
y0 += lines + 2
case *bug.CommentTimelineItem:
comment := op.(*bug.CommentTimelineItem)
case *bug.AddCommentTimelineItem:
comment := op.(*bug.AddCommentTimelineItem)
edited := ""
if comment.Edited() {
@ -277,13 +277,13 @@ func (sb *showBug) renderMain(g *gocui.Gui, mainView *gocui.View) error {
fmt.Fprint(v, content)
y0 += lines + 2
case *bug.SetTitleOperation:
setTitle := op.(*bug.SetTitleOperation)
case *bug.SetTitleTimelineItem:
setTitle := op.(*bug.SetTitleTimelineItem)
content := fmt.Sprintf("%s changed the title to %s on %s",
colors.Magenta(setTitle.Author.Name),
colors.Bold(setTitle.Title),
setTitle.Time().Format(timeLayout),
setTitle.UnixTime.Time().Format(timeLayout),
)
content, lines := text.Wrap(content, maxX)
@ -294,13 +294,13 @@ func (sb *showBug) renderMain(g *gocui.Gui, mainView *gocui.View) error {
fmt.Fprint(v, content)
y0 += lines + 2
case *bug.SetStatusOperation:
setStatus := op.(*bug.SetStatusOperation)
case *bug.SetStatusTimelineItem:
setStatus := op.(*bug.SetStatusTimelineItem)
content := fmt.Sprintf("%s %s the bug on %s",
colors.Magenta(setStatus.Author.Name),
colors.Bold(setStatus.Status.Action()),
setStatus.Time().Format(timeLayout),
setStatus.UnixTime.Time().Format(timeLayout),
)
content, lines := text.Wrap(content, maxX)
@ -311,8 +311,8 @@ func (sb *showBug) renderMain(g *gocui.Gui, mainView *gocui.View) error {
fmt.Fprint(v, content)
y0 += lines + 2
case *bug.LabelChangeOperation:
labelChange := op.(*bug.LabelChangeOperation)
case *bug.LabelChangeTimelineItem:
labelChange := op.(*bug.LabelChangeTimelineItem)
var added []string
for _, label := range labelChange.Added {
@ -349,7 +349,7 @@ func (sb *showBug) renderMain(g *gocui.Gui, mainView *gocui.View) error {
content := fmt.Sprintf("%s %s on %s",
colors.Magenta(labelChange.Author.Name),
action.String(),
labelChange.Time().Format(timeLayout),
labelChange.UnixTime.Time().Format(timeLayout),
)
content, lines := text.Wrap(content, maxX)