Skip to content
This repository has been archived by the owner on Apr 5, 2024. It is now read-only.

fnutils and errutils test cases, inline docs, listall fnc fix #82

Merged
merged 5 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions errutils/errutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ import (
"fmt"
)

// FmtError formats an error message using a format string and optional values,
// and returns it as an error object.
//
// It takes a format string f and variadic arguments v, and uses them to construct
// the error message by calling fmt.Sprintf function. The resulting error message
// is then wrapped into an error object using errors.New.
//
// Example:
//
// err := FmtError("Invalid input: %s", userInput)
// if err != nil {
// log.Println(err)
// }
//
// @param f The format string specifying the error message.
// @param v Optional values to be inserted into the format string.
//
// @returns An error object containing the formatted error message.
func FmtError(f string, v ...any) error {
return errors.New(fmt.Sprintf(f, v...))
}
25 changes: 25 additions & 0 deletions errutils/errutils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package errutils

import (
"errors"
"fmt"
"testing"
)

func TestFmtError(t *testing.T) {
t.Run("Testing execution of error utils", func(t *testing.T) {
want := errors.New("testing error utils")
got := FmtError("testing error utils")
if got.Error() != want.Error() {
t.Errorf("invalid error string generated")
}
})

t.Run("Testing execution of error utils with formatting", func(t *testing.T) {
want := errors.New(fmt.Sprintf("expecting errors %d", 0))
got := FmtError("expecting errors %d", 0)
if got.Error() != want.Error() {
t.Errorf("invalid error string generated")
}
})
}
59 changes: 59 additions & 0 deletions fnutils/fn.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,76 @@ import (
"time"
)

// ExecuteAfterSecs executes the given function after the specified timeout duration,
// expressed in seconds.
//
// It converts the timeout value from seconds to a duration in seconds and then calls
// the ExecuteAfter function, passing the converted duration and the provided function.
//
// Example:
//
// ExecuteAfterSecs(func() {
// fmt.Println("Hello, World!")
// }, 10)
//
// @param fn The function to be executed.
//
// @param timeout The timeout duration in seconds.
func ExecuteAfterSecs(fn func(), timeout int) {
ExecuteAfter(fn, time.Second*time.Duration(timeout))
}

// ExecuteAfterMs executes the given function after the specified timeout duration,
// expressed in milliseconds.
//
// It converts the timeout value from milliseconds to a duration in seconds and then calls
// the ExecuteAfter function, passing the converted duration and the provided function.
//
// Example:
//
// ExecuteAfterMs(func() {
// fmt.Println("Hello, World!")
// }, 1000)
//
// @param fn The function to be executed.
//
// @param timeout The timeout duration in milliseconds.
func ExecuteAfterMs(fn func(), timeout int64) {
ExecuteAfter(fn, time.Millisecond*time.Duration(timeout))
}

// ExecuteAfterMin executes the given function after the specified timeout duration,
// expressed in minutes.
//
// It converts the timeout value from minutes to a duration in seconds and then calls
// the ExecuteAfter function, passing the converted duration and the provided function.
//
// Example:
//
// ExecuteAfterMin(func() {
// fmt.Println("Hello, World!")
// }, 5)
//
// @param fn The function to be executed.
//
// @param timeout The timeout duration in minutes.
func ExecuteAfterMin(fn func(), timeout int) {
ExecuteAfter(fn, time.Minute*time.Duration(timeout))
}

// ExecuteAfter executes the given function after the specified timeout duration.
//
// It waits for the specified duration and then calls the provided function.
//
// Example:
//
// ExecuteAfter(func() {
// fmt.Println("Hello, World!")
// }, time.Second)
//
// @param fn The function to be executed.
//
// @param timeout The duration to wait before executing the function.
func ExecuteAfter(fn func(), timeout time.Duration) {
select {
case <-time.After(timeout):
Expand Down
140 changes: 140 additions & 0 deletions fnutils/fn_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package fnutils

import (
"testing"
"time"
)

func TestExecuteAfter(t *testing.T) {
t.Run("Execution occurs after the specified timeout", func(t *testing.T) {
executed := false
fn := func() {
executed = true
}
timeout := 5 * time.Second

ExecuteAfter(fn, timeout)

if !executed {
t.Error("Expected execution to occur after the specified timeout")
}
})

t.Run("Execution occurs immediately when timeout is zero", func(t *testing.T) {
executed := false
fn := func() {
executed = true
}
timeout := 0 * time.Second

ExecuteAfter(fn, timeout)

if !executed {
t.Error("Expected execution to occur immediately")
}
})

t.Run("Execution occurs only once", func(t *testing.T) {
counter := 0
fn := func() {
counter++
}
timeout := 1 * time.Second

ExecuteAfter(fn, timeout)
time.Sleep(2 * time.Second)

if counter != 1 {
t.Errorf("Expected execution to occur once, got %d times", counter)
}
})
//
//t.Run("Multiple executions occur if the function takes longer than the timeout", func(t *testing.T) {
// executionCount := 0
// fn := func() {
// executionCount++
// time.Sleep(2 * time.Second)
// }
// timeout := 1 * time.Second
//
// go ExecuteAfter(fn, timeout)
// time.Sleep(3 * time.Second)
//
// if executionCount != 2 {
// t.Errorf("Expected execution to occur twice, got %d times", executionCount)
// }
//})
//
//t.Run("No execution occurs if the function is nil", func(t *testing.T) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nandagopalan same here, if we need to handle this condition in our logic

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may have to put a nil check in the code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am approving this PR we will add that as a separate issue.

// _ = func() {
// // This function should not be executed
// t.Error("Function should not be executed")
// }
// timeout := 1 * time.Second
//
// ExecuteAfter(nil, timeout)
//})
//
//t.Run("No execution occurs if the timeout is set to 0 and the function is nil", func(t *testing.T) {
// _ = func() {
// // This function should not be executed
// t.Error("Function should not be executed")
// }
// timeout := 0 * time.Second
//
// ExecuteAfter(nil, timeout)
//})
//
//t.Run("Execution does not occur when timeout is negative", func(t *testing.T) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nandagopalan have a look at this condition if we need to cater for this in our logic

// executed := false
// fn := func() {
// executed = true
// }
// timeout := -1 * time.Second
//
// ExecuteAfter(fn, timeout)
//
// if executed {
// t.Error("Expected execution to not occur with negative timeout")
// }
//})
}

func TestExecuteAfterSecs(t *testing.T) {
t.Run("Execution after specific timeout (seconds)", func(t *testing.T) {
executed := false
fn := func() {
executed = true
}
ExecuteAfterSecs(fn, 5)
if !executed {
t.Error("Expected execution to occur after the specified timeout")
}
})
}

func TestExecuteAfterMs(t *testing.T) {
t.Run("Execution after specific timeout (milliseconds)", func(t *testing.T) {
executed := false
fn := func() {
executed = true
}
ExecuteAfterMs(fn, 50)
if !executed {
t.Error("Expected execution to occur after the specified timeout")
}
})
}

func TestExecuteAfterMin(t *testing.T) {
t.Run("Execution after specific timeout (minutes)", func(t *testing.T) {
executed := false
fn := func() {
executed = true
}
ExecuteAfterMin(fn, 1)
if !executed {
t.Error("Expected execution to occur after the specified timeout")
}
})
}
43 changes: 41 additions & 2 deletions vfs/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,47 @@
# Virtual File System (VFS) Package
The VFS package provides a unified api for accessing multple file system. It is extensible and new implementation can be
The VFS package provides a unified api for accessing multiple file system. It is extensible and new implementation can be
easily plugged in.


The default package has methods for local file system.

---
- [Installation](#installation)
- [Usage](#usage)
---

### Installation
```bash
go get go.nandlabs.io/commons/vfs
```

### Usage
A simple usage of the library to create a directory in the OS.

```go
package main

import (
"fmt"
"go.nandlabs.io/commons/vfs"
)

var (
testManager = GetManager()
)

func GetRawPath(input string) (output string) {
currentPath, _ := os.Getwd()
u, _ := url.Parse(input)
path := currentPath + u.Path
output = u.Scheme + "://" + path
return
}

func main() {
u := GetRawPath("file:///test-data")
_, err := testManager.MkdirRaw(u)
if err != nil {
fmt.Errorf("MkdirRaw() error = %v", err)
}
}
```
3 changes: 0 additions & 3 deletions vfs/base_fs.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package vfs

import (
"fmt"
"io"
"net/url"

Expand Down Expand Up @@ -185,12 +184,10 @@ func (b *BaseVFS) Walk(u *url.URL, fn WalkFn) (err error) {
if err == nil {
if srcFi.IsDir() {
children, err = src.ListAll()
fmt.Println(children)
if err == nil {
for _, child := range children {
childInfo, err = child.Info()
if err == nil {

if childInfo.IsDir() {
err = b.Walk(child.Url(), fn)
} else {
Expand Down
Loading