Skip to content

Commit

Permalink
test(kernel): add universal unit tests (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
plastikfan committed Jul 2, 2024
1 parent bb1a6a7 commit 01885f1
Show file tree
Hide file tree
Showing 3 changed files with 302 additions and 40 deletions.
1 change: 0 additions & 1 deletion internal/kernel/kernel-support_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ func universalCallback(name string) core.Client {

func subscribes(subscription enums.Subscription, de fs.DirEntry) bool {
isAnySubscription := (subscription == enums.SubscribeUniversal)

files := (subscription == enums.SubscribeFiles) && (!de.IsDir())
folders := ((subscription == enums.SubscribeFolders) ||
subscription == enums.SubscribeFoldersWithFiles) && (de.IsDir())
Expand Down
156 changes: 117 additions & 39 deletions internal/kernel/navigator-universal_test.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package kernel_test

import (
"context"
"fmt"
"io/fs"
"path/filepath"
"strings"
"testing/fstest"

"github.com/fortytw2/leaktest"
. "github.com/onsi/ginkgo/v2" //nolint:revive // ok
. "github.com/onsi/gomega" //nolint:revive // ok

tv "github.com/snivilised/traverse"
"github.com/snivilised/traverse/enums"
"github.com/snivilised/traverse/internal/helpers"
"github.com/snivilised/traverse/internal/lo"
"github.com/snivilised/traverse/internal/services"
"github.com/snivilised/traverse/pref"
)

var _ = Describe("NavigatorUniversal", Ordered, func() {
Expand All @@ -27,7 +28,7 @@ var _ = Describe("NavigatorUniversal", Ordered, func() {
const (
verbose = true
)
var portion = filepath.Join("MUSICO", "bass")
var portion = filepath.Join("MUSICO", "RETRO-WAVE")
vfs, root = helpers.Musico(portion, verbose)
Expect(root).NotTo(BeEmpty())
})
Expand All @@ -36,42 +37,119 @@ var _ = Describe("NavigatorUniversal", Ordered, func() {
services.Reset()
})

Context("nav", func() {
When("foo", func() {
It("🧪 should: not fail", func(specCtx SpecContext) {
defer leaktest.Check(GinkgoT())()

ctx, cancel := context.WithCancel(specCtx)
defer cancel()

result, err := tv.Walk().Configure().Extent(tv.Prime(
&tv.Using{
Root: root,
Subscription: tv.SubscribeUniversal,
Handler: func(node *tv.Node) error {
fmt.Printf("🌀 node: '%v'\n", node.Path)

return nil
},
GetFS: func() fs.FS {
return vfs
},
DescribeTable("Ensure Callback Invoked Once", Label("simple", "RETRO-WAVE"),
func(ctx SpecContext, entry *naviTE) {
recording := make(recordingMap)
visited := []string{}

once := func(node *tv.Node) error {
_, found := recording[node.Path]
Expect(found).To(BeFalse())
recording[node.Path] = len(node.Children)

return entry.callback(node)
}

visitor := func(node *tv.Node) error {
return once(node)
}

callback := lo.Ternary(entry.once, once,
lo.Ternary(entry.visit, visitor, entry.callback),
)
path := helpers.Path(root, entry.relative)

result, err := tv.Walk().Configure().Extent(tv.Prime(
&tv.Using{
Root: path,
Subscription: entry.subscription,
Handler: callback,
GetFS: func() fs.FS {
return vfs
},
},
tv.WithOnBegin(begin("🛡️")),
tv.WithSortBehaviour(&pref.SortBehaviour{
IsCaseSensitive: entry.caseSensitive,
}),
tv.WithHookQueryStatus(func(path string) (fs.FileInfo, error) {
return vfs.Stat(helpers.TrimRoot(path))
}),
tv.WithHookReadDirectory(func(_ fs.FS, dirname string) ([]fs.DirEntry, error) {
return vfs.ReadDir(helpers.TrimRoot(dirname))
}),
),
).Navigate(ctx)

tv.WithHookQueryStatus(func(path string) (fs.FileInfo, error) {
return vfs.Stat(helpers.TrimRoot(path))
}),
tv.WithHookReadDirectory(func(_ fs.FS, dirname string) ([]fs.DirEntry, error) {
return vfs.ReadDir(helpers.TrimRoot(dirname))
}),
),
).Navigate(ctx)

Expect(err).To(Succeed())
Expect(result.Metrics().Count(enums.MetricNoFilesInvoked)).To(BeEquivalentTo(37))
Expect(result.Metrics().Count(enums.MetricNoFoldersInvoked)).To(BeEquivalentTo(13))
Expect(result.Session()).NotTo(BeNil())
})
})
})
_ = result.Session().StartedAt()
_ = result.Session().Elapsed()

if entry.visit {
_ = filepath.WalkDir(path, func(path string, de fs.DirEntry, _ error) error {
if strings.HasSuffix(path, ".DS_Store") {
return nil
}

if subscribes(entry.subscription, de) {
visited = append(visited, path)
}
return nil
})
}

if entry.visit {
every := lo.EveryBy(visited, func(p string) bool {
_, found := recording[p]
return found
})
Expect(every).To(BeTrue())
}

Expect(err).To(Succeed())
Expect(result.Metrics().Count(enums.MetricNoFilesInvoked)).To(
Equal(entry.expectedNoOf.files), "Incorrect no of files",
)
Expect(result.Metrics().Count(enums.MetricNoFoldersInvoked)).To(
Equal(entry.expectedNoOf.folders), "Incorrect no of folders",
)
},
func(entry *naviTE) string {
return fmt.Sprintf("🧪 ===> given: '%v'", entry.message)
},

// === universal =====================================================

Entry(nil, &naviTE{
message: "universal: Path is leaf",
relative: "RETRO-WAVE/Chromatics/Night Drive",
subscription: enums.SubscribeUniversal,
callback: universalCallback("LEAF-PATH"),
expectedNoOf: directoryQuantities{
files: 4,
folders: 1,
},
}),

Entry(nil, &naviTE{
message: "universal: Path contains folders",
relative: "RETRO-WAVE",
subscription: enums.SubscribeUniversal,
callback: universalCallback("CONTAINS-FOLDERS"),
expectedNoOf: directoryQuantities{
files: 14,
folders: 8,
},
}),
Entry(nil, &naviTE{
message: "universal: Path contains folders (visit)",
relative: "RETRO-WAVE",
visit: true,
subscription: enums.SubscribeUniversal,
callback: universalCallback("VISIT-CONTAINS-FOLDERS"),
expectedNoOf: directoryQuantities{
files: 14,
folders: 8,
},
}),
)
})
185 changes: 185 additions & 0 deletions internal/lo/intersect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
package lo

// Contains returns true if an element is present in a collection.
func Contains[T comparable](collection []T, element T) bool {
for _, item := range collection {
if item == element {
return true
}
}

return false
}

// ContainsBy returns true if predicate function return true.
func ContainsBy[T any](collection []T, predicate func(item T) bool) bool {
for _, item := range collection {
if predicate(item) {
return true
}
}

return false
}

// Every returns true if all elements of a subset are contained into a collection or if the subset is empty.
func Every[T comparable](collection, subset []T) bool {
for _, elem := range subset {
if !Contains(collection, elem) {
return false
}
}

return true
}

// EveryBy returns true if the predicate returns true for all of the elements in the collection or if the collection is empty.
func EveryBy[T any](collection []T, predicate func(item T) bool) bool {
for _, v := range collection {
if !predicate(v) {
return false
}
}

return true
}

// Some returns true if at least 1 element of a subset is contained into a collection.
// If the subset is empty Some returns false.
func Some[T comparable](collection, subset []T) bool {
for _, elem := range subset {
if Contains(collection, elem) {
return true
}
}

return false
}

// SomeBy returns true if the predicate returns true for any of the elements in the collection.
// If the collection is empty SomeBy returns false.
func SomeBy[T any](collection []T, predicate func(item T) bool) bool {
for _, v := range collection {
if predicate(v) {
return true
}
}

return false
}

// None returns true if no element of a subset are contained into a collection or if the subset is empty.
func None[T comparable](collection, subset []T) bool {
for _, elem := range subset {
if Contains(collection, elem) {
return false
}
}

return true
}

// NoneBy returns true if the predicate returns true for none of the elements in the collection or if the collection is empty.
func NoneBy[T any](collection []T, predicate func(item T) bool) bool {
for _, v := range collection {
if predicate(v) {
return false
}
}

return true
}

// Intersect returns the intersection between two collections.
func Intersect[T comparable](list1, list2 []T) []T {
result := []T{}
seen := map[T]struct{}{}

for _, elem := range list1 {
seen[elem] = struct{}{}
}

for _, elem := range list2 {
if _, ok := seen[elem]; ok {
result = append(result, elem)
}
}

return result
}

// Difference returns the difference between two collections.
// The first value is the collection of element absent of list2.
// The second value is the collection of element absent of list1.
func Difference[T comparable](list1, list2 []T) (left, right []T) {
left = []T{}
right = []T{}

seenLeft := map[T]struct{}{}
seenRight := map[T]struct{}{}

for _, elem := range list1 {
seenLeft[elem] = struct{}{}
}

for _, elem := range list2 {
seenRight[elem] = struct{}{}
}

for _, elem := range list1 {
if _, ok := seenRight[elem]; !ok {
left = append(left, elem)
}
}

for _, elem := range list2 {
if _, ok := seenLeft[elem]; !ok {
right = append(right, elem)
}
}

return left, right
}

// Union returns all distinct elements from given collections.
// result returns will not change the order of elements relatively.
func Union[T comparable](lists ...[]T) []T {
result := []T{}
seen := map[T]struct{}{}

for _, list := range lists {
for _, e := range list {
if _, ok := seen[e]; !ok {
seen[e] = struct{}{}
result = append(result, e)
}
}
}

return result
}

// Without returns slice excluding all given values.
func Without[T comparable](collection []T, exclude ...T) []T {
result := make([]T, 0, len(collection))
for _, e := range collection {
if !Contains(exclude, e) {
result = append(result, e)
}
}
return result
}

// WithoutEmpty returns slice excluding empty values.
func WithoutEmpty[T comparable](collection []T) []T {
var empty T

result := make([]T, 0, len(collection))
for _, e := range collection {
if e != empty {
result = append(result, e)
}
}

return result
}

0 comments on commit 01885f1

Please sign in to comment.