mirror of
https://github.com/Bornholm/formidable.git
synced 2025-07-16 02:21:34 +02:00
feat: url based data loading system
This commit is contained in:
31
internal/data/scheme/file/loader_handler.go
Normal file
31
internal/data/scheme/file/loader_handler.go
Normal file
@ -0,0 +1,31 @@
|
||||
package file
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const SchemeFile = "file"
|
||||
|
||||
type LoaderHandler struct{}
|
||||
|
||||
func (h *LoaderHandler) Match(url *url.URL) bool {
|
||||
return url.Scheme == SchemeFile || url.Scheme == ""
|
||||
}
|
||||
|
||||
func (h *LoaderHandler) Open(url *url.URL) (io.ReadCloser, error) {
|
||||
file, err := os.Open(filepath.Join(url.Host, url.Path))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not open file '%s'", url.Path)
|
||||
}
|
||||
|
||||
return file, nil
|
||||
}
|
||||
|
||||
func NewLoaderHandler() *LoaderHandler {
|
||||
return &LoaderHandler{}
|
||||
}
|
107
internal/data/scheme/file/loader_handler_test.go
Normal file
107
internal/data/scheme/file/loader_handler_test.go
Normal file
@ -0,0 +1,107 @@
|
||||
package file
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const dummyFilePath = "testdata/dummy.txt"
|
||||
|
||||
var loaderHandlerTestCases []loaderHandlerTestCase
|
||||
|
||||
func init() {
|
||||
dummyFileAbsolutePath, err := filepath.Abs(dummyFilePath)
|
||||
if err != nil {
|
||||
panic(errors.WithStack(err))
|
||||
}
|
||||
|
||||
loaderHandlerTestCases = []loaderHandlerTestCase{
|
||||
{
|
||||
URL: SchemeFile + "://" + dummyFilePath,
|
||||
ExpectMatch: true,
|
||||
ExpectOpenError: false,
|
||||
ExpectOpenContent: "dummy",
|
||||
},
|
||||
{
|
||||
URL: dummyFilePath,
|
||||
ExpectMatch: true,
|
||||
ExpectOpenError: false,
|
||||
ExpectOpenContent: "dummy",
|
||||
},
|
||||
{
|
||||
URL: dummyFileAbsolutePath,
|
||||
ExpectMatch: true,
|
||||
ExpectOpenError: false,
|
||||
ExpectOpenContent: "dummy",
|
||||
},
|
||||
{
|
||||
URL: SchemeFile + "://" + dummyFileAbsolutePath,
|
||||
ExpectMatch: true,
|
||||
ExpectOpenError: false,
|
||||
ExpectOpenContent: "dummy",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type loaderHandlerTestCase struct {
|
||||
URL string
|
||||
ExpectMatch bool
|
||||
ExpectOpenError bool
|
||||
ExpectOpenContent string
|
||||
}
|
||||
|
||||
func TestLoaderHandler(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
handler := NewLoaderHandler()
|
||||
|
||||
for _, tc := range loaderHandlerTestCases {
|
||||
func(tc loaderHandlerTestCase) {
|
||||
t.Run(fmt.Sprintf("Load '%s'", tc.URL), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
url, err := url.Parse(tc.URL)
|
||||
if err != nil {
|
||||
t.Fatal(errors.Wrapf(err, "could not parse url '%s'", tc.URL))
|
||||
}
|
||||
|
||||
if e, g := tc.ExpectMatch, handler.Match(url); e != g {
|
||||
t.Errorf("URL '%s': expected matching result '%v', got '%v'", tc.URL, e, g)
|
||||
}
|
||||
|
||||
if !tc.ExpectMatch {
|
||||
return
|
||||
}
|
||||
|
||||
reader, err := handler.Open(url)
|
||||
if err != nil && !tc.ExpectOpenError {
|
||||
t.Fatal(errors.Wrapf(err, "could not open url '%s'", url.String()))
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := reader.Close(); err != nil {
|
||||
t.Error(errors.WithStack(err))
|
||||
}
|
||||
}()
|
||||
|
||||
if tc.ExpectOpenError {
|
||||
t.Fatal(errors.Errorf("no error was returned as expected when opening url '%s'", url.String()))
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
t.Fatal(errors.WithStack(err))
|
||||
}
|
||||
|
||||
if e, g := tc.ExpectOpenContent, string(data); e != g {
|
||||
t.Errorf("URL '%s': expected content'%v', got '%v'", tc.URL, e, g)
|
||||
}
|
||||
})
|
||||
}(tc)
|
||||
}
|
||||
}
|
1
internal/data/scheme/file/testdata/dummy.txt
vendored
Normal file
1
internal/data/scheme/file/testdata/dummy.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
dummy
|
Reference in New Issue
Block a user