Skip to content

Commit

Permalink
feat: add diff util
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisgacsal committed Sep 19, 2024
1 parent d4bb4cf commit 1a51f9d
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 0 deletions.
66 changes: 66 additions & 0 deletions pkg/diff/diff.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package diff

import "github.com/samber/lo"

type Diff[T comparable, S ~[]T] struct {
additionsMap map[T]struct{}
additions S

removalsMap map[T]struct{}
removals S
}

func (d Diff[T, S]) Has(item T) bool {
return d.InAdditions(item) || d.InRemovals(item)
}

func (d Diff[T, S]) InAdditions(item T) bool {
if _, ok := d.additionsMap[item]; ok {
return true
}

return false
}

func (d Diff[T, S]) InRemovals(item T) bool {
if _, ok := d.removalsMap[item]; ok {
return true
}

return false
}

func (d Diff[T, S]) Additions() S {
return d.additions
}

func (d Diff[T, S]) Removals() S {
return d.removals
}

func (d Diff[T, S]) HasChanged() bool {
return len(d.additions) > 0 || len(d.removals) > 0
}

func (d Diff[T, S]) Changed() S {
return append(d.additions, d.removals...)
}

func New[T comparable, S ~[]T](base, new S) *Diff[T, S] {
additions, removals := lo.Difference(base, new)

additionsMap := lo.SliceToMap(additions, func(item T) (T, struct{}) {
return item, struct{}{}
})

removalsMap := lo.SliceToMap(removals, func(item T) (T, struct{}) {
return item, struct{}{}
})

return &Diff[T, S]{
additionsMap: additionsMap,
additions: additions,
removalsMap: removalsMap,
removals: removals,
}
}
85 changes: 85 additions & 0 deletions pkg/diff/diff_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package diff

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestDiff(t *testing.T) {
tests := []struct {
Name string

Base []string
New []string

ExpectedAdditions []string
ExpectedRemovals []string
}{
{
Name: "No change",
Base: []string{
"diff-1",
"diff-2",
},
New: []string{
"diff-2",
"diff-1",
},
},
{
Name: "Add new item",
Base: []string{
"diff-1",
"diff-2",
"diff-3",
},
New: []string{
"diff-2",
"diff-1",
},
ExpectedAdditions: []string{
"diff-3",
},
},
{
Name: "Remove old item",
Base: []string{
"diff-2",
},
New: []string{
"diff-2",
"diff-1",
},
ExpectedRemovals: []string{
"diff-1",
},
},
{
Name: "Add and remove items",
Base: []string{
"diff-1",
"diff-3",
},
New: []string{
"diff-2",
"diff-1",
},
ExpectedAdditions: []string{
"diff-3",
},
ExpectedRemovals: []string{
"diff-2",
},
},
}

for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
diff := New(test.Base, test.New)

assert.ElementsMatch(t, test.ExpectedAdditions, diff.Additions())
assert.ElementsMatch(t, test.ExpectedRemovals, diff.Removals())
})
}
}

0 comments on commit 1a51f9d

Please sign in to comment.