🗃️ Created basic pages FileSystem repository implementation
This commit is contained in:
parent
a9586897b3
commit
fe19646f7e
|
@ -0,0 +1,64 @@
|
|||
package fs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/adrg/frontmatter"
|
||||
"golang.org/x/text/language"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"source.toby3d.me/toby3d/home/internal/domain"
|
||||
"source.toby3d.me/toby3d/home/internal/page"
|
||||
)
|
||||
|
||||
type (
|
||||
Page struct {
|
||||
Title string `yaml:"title"`
|
||||
Params map[string]any `yaml:",inline"`
|
||||
Content []byte `yaml:"-"`
|
||||
}
|
||||
|
||||
fileSystemPageRepository struct {
|
||||
dir fs.FS
|
||||
rootPath string
|
||||
}
|
||||
)
|
||||
|
||||
var FrontMatterFormats = []*frontmatter.Format{
|
||||
frontmatter.NewFormat(`---`, `---`, yaml.Unmarshal),
|
||||
}
|
||||
|
||||
func NewFileSystemPageRepository(rootDir fs.FS) page.Repository {
|
||||
return &fileSystemPageRepository{
|
||||
dir: rootDir,
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *fileSystemPageRepository) Get(ctx context.Context, lang language.Tag, path string) (*domain.Page, error) {
|
||||
target := "index." + lang.String() + ".md"
|
||||
if lang == language.Und {
|
||||
target = "index.md"
|
||||
}
|
||||
|
||||
target = filepath.Join(path, target)
|
||||
|
||||
f, err := repo.dir.Open(target)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot open '%s' page file: %w", target, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
data := new(Page)
|
||||
if data.Content, err = frontmatter.Parse(f, data, FrontMatterFormats...); err != nil {
|
||||
return nil, fmt.Errorf("cannot parse page content as FrontMatter: %w", err)
|
||||
}
|
||||
|
||||
return &domain.Page{
|
||||
Language: lang,
|
||||
Title: data.Title,
|
||||
Content: data.Content,
|
||||
}, nil
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package fs_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"source.toby3d.me/toby3d/home/internal/domain"
|
||||
repository "source.toby3d.me/toby3d/home/internal/page/repository/fs"
|
||||
)
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testData := fstest.MapFS{
|
||||
filepath.Join("index.ru.md"): &fstest.MapFile{
|
||||
Data: []byte("---\ntitle: страница\n---\nпривет, мир!\n"),
|
||||
},
|
||||
filepath.Join("dir", "index.en.md"): &fstest.MapFile{
|
||||
Data: []byte("---\ntitle: page\n---\nhello, world!\n"),
|
||||
},
|
||||
}
|
||||
|
||||
repo := repository.NewFileSystemPageRepository(testData)
|
||||
|
||||
for name, tc := range map[string]struct {
|
||||
lang language.Tag
|
||||
expect *domain.Page
|
||||
path string
|
||||
}{
|
||||
"file": {
|
||||
lang: language.English,
|
||||
path: path.Join("dir"),
|
||||
expect: &domain.Page{
|
||||
Language: language.English,
|
||||
Title: "page",
|
||||
Content: []byte("hello, world!\n"),
|
||||
},
|
||||
},
|
||||
"dir": {
|
||||
lang: language.Russian,
|
||||
path: path.Join(""),
|
||||
expect: &domain.Page{
|
||||
Language: language.Russian,
|
||||
Title: "страница",
|
||||
Content: []byte("привет, мир!\n"),
|
||||
},
|
||||
},
|
||||
} {
|
||||
name, tc := name, tc
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
out, err := repo.Get(context.Background(), tc.lang, tc.path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(out, tc.expect, cmp.AllowUnexported(language.Und)); diff != "" {
|
||||
t.Error(diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue