Skip to content
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
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ jobs:
- run: nix develop --ignore-environment --command make vendor

- run: nix develop --ignore-environment --command make fmt-check
- run: nix develop --ignore-environment --command make lint
- run: nix develop --ignore-environment --command make vet
- run: nix develop --ignore-environment --command make test
- run: nix develop --ignore-environment --command make test
13 changes: 13 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: "2"

linters:
default: none
enable:
- godox

issues:
max-issues-per-linter: 0
max-same-issues: 0

run:
modules-download-mode: vendor
4 changes: 4 additions & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ packages:
litdoc/internal:
interfaces:
Cell:
config:
dir: ./internal/
pkgname: internal_test
CellParser:
config:
dir: ./internal/
pkgname: internal_test
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
GO ?= go

.PHONY: pre-pr
pre-pr: clean mock fmt-check vet test
pre-pr: clean mock fmt-check lint vet test

.PHONY: fmt
fmt:
Expand All @@ -20,6 +20,10 @@ fmt-check:
vet:
@$(GO) vet ./...

.PHONY: lint
lint: vendor
@golangci-lint run ./...

.PHONY: mock
mock:
@mockery
Expand Down
8 changes: 7 additions & 1 deletion cmd/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"path/filepath"

"litdoc/internal"
"litdoc/internal/bash"
"litdoc/internal/static"

"github.com/spf13/cobra"
)
Expand All @@ -18,7 +20,11 @@ var fileCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
path := args[0]
data, err := internal.ProcessFile(path)
parsers := map[string]internal.CellParser{
"static": internal.CellParserFunc(static.ParseCell),
"bash": internal.CellParserFunc(bash.ParseCell),
}
data, err := internal.ProcessFile(path, parsers)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
Expand Down
3 changes: 2 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
devShells.default = pkgs.mkShell {
packages = with pkgs; [
go
golangci-lint
go-mockery
cacert
];
Expand All @@ -27,4 +28,4 @@
};
}
);
}
}
112 changes: 112 additions & 0 deletions internal/CellParser_mock_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 57 additions & 0 deletions internal/bash/cell.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package bash

import (
"fmt"

"litdoc/internal"
)

type Cell struct {
block internal.Block
output internal.Output
}

func MakeCellFromRaw(content, indent string, output internal.Output) Cell {
return Cell{
block: internal.MakeBlockFromRaw(internal.BlockKindFencedCode, content, indent, false),
output: output,
}
}

func ParseCell(
block internal.Block,
following []internal.Block,
) (
internal.Cell,
int,
error,
) {
return parseCellWith(block, following, internal.OutputFromBlocks)
}

func parseCellWith(
block internal.Block,
following []internal.Block,
parseOutput func(internal.Block, []internal.Block) (internal.Output, int, error),
) (
internal.Cell,
int,
error,
) {
output, consumed, err := parseOutput(block, following)
if err != nil {
return nil, 0, fmt.Errorf("parsing output: %w", err)
}
return Cell{block: block, output: output}, consumed, nil
}

func (c Cell) Execute() (internal.Cell, error) {
return Cell{
block: c.block,
output: internal.MakeOutput("output", c.block.Indent()),
}, nil
}

func (c Cell) Render() (string, error) {
return c.block.Render() + c.output.Render(), nil
}
135 changes: 135 additions & 0 deletions internal/bash/cell_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package bash_test

import (
"strings"
"testing"

"litdoc/internal"
"litdoc/internal/bash"

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

func joinLines(lines ...string) string {
return strings.Join(lines, "\n")
}

func TestMakeCellFromRaw(t *testing.T) {
// given
code := joinLines(
"```bash",
"echo hello",
"```",
"",
)
output := internal.MakeOutput("hello", "")
cell := bash.MakeCellFromRaw(code, "", output)

// when
got, err := cell.Render()

// then
require.NoError(t, err)
assert.Equal(t, "```bash\necho hello\n```\n"+output.Render(), got)
}

func TestParseCellWith(t *testing.T) {
block := internal.MakeBlockFromRaw(internal.BlockKindFencedCode, joinLines(
"```bash",
"echo hello",
"```",
"",
), "", false)

t.Run("assembles cell from block and output", func(t *testing.T) {
// given
output := internal.MakeOutput("hello", "")
parseOutput := func(internal.Block, []internal.Block) (internal.Output, int, error) {
return output, 3, nil
}

// when
cell, consumed, err := bash.ParseCellWith(block, nil, parseOutput)

// then
require.NoError(t, err)
assert.Equal(t, 3, consumed)
rendered, err := cell.Render()
require.NoError(t, err)
assert.Equal(t, block.Render()+output.Render(), rendered)
})

t.Run("output parsing error is wrapped", func(t *testing.T) {
// given
parseOutput := func(internal.Block, []internal.Block) (internal.Output, int, error) {
return internal.Output{}, 0, assert.AnError
}

// when
_, _, err := bash.ParseCellWith(block, nil, parseOutput)

// then
require.ErrorContains(t, err, "parsing output")
require.ErrorIs(t, err, assert.AnError)
})
}

func TestRender(t *testing.T) {
t.Run("without output", func(t *testing.T) {
// given
code := joinLines(
"```bash",
"echo hello",
"```",
"",
)
cell := bash.MakeCellFromRaw(code, "", internal.MakeOutput("", ""))

// when
gotContent, err := cell.Render()

// then
require.NoError(t, err)
assert.Equal(t, code, gotContent)
})

t.Run("with output", func(t *testing.T) {
// given
fencedCode := joinLines(
"```bash",
"echo hello",
"```",
"",
)
output := internal.MakeOutput("hello", "")
cell := bash.MakeCellFromRaw(fencedCode, "", output)

// when
gotContent, err := cell.Render()

// then
require.NoError(t, err)
assert.Equal(t, fencedCode+output.Render(), gotContent)
})
}

func TestExecute(t *testing.T) {
// given
fencedCode := joinLines(
"```bash",
"echo hello",
"```",
"",
)
cell := bash.MakeCellFromRaw(fencedCode, "", internal.MakeOutput("", ""))

// when
gotCell, err := cell.Execute()

// then
require.NoError(t, err)
rendered, err := gotCell.Render()
require.NoError(t, err)
assert.Equal(t, fencedCode+internal.MakeOutput("output", "").Render(), rendered)
}
Loading
Loading