Skip to content

Commit

Permalink
feat: add normalise command
Browse files Browse the repository at this point in the history
  • Loading branch information
kangasta committed Dec 17, 2024
1 parent 99517b7 commit fd65b96
Show file tree
Hide file tree
Showing 7 changed files with 305 additions and 79 deletions.
56 changes: 54 additions & 2 deletions cmd/cmd_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
package cmd

import (
"os"
"path/filepath"
"testing"

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

func TestRoot_testdata(t *testing.T) {
Expand Down Expand Up @@ -35,9 +39,57 @@ func TestRoot_testdata(t *testing.T) {
t.Run(test.testPath, func(t *testing.T) {
rootCmd.SetArgs([]string{test.testPath})
exitCode := Execute()
if exitCode != test.exitCode {
t.Errorf("Expected exit code %d, got %d", test.exitCode, exitCode)
assert.Equal(t, test.exitCode, exitCode)
})
}
}

func TestNormalise_testdata(t *testing.T) {
for _, test := range []struct {
testPath string
transformsArgs []string
exitCode int
output string
}{
{
testPath: "../testdata/success_normalise_infotexts.md",
transformsArgs: []string{"-t", "filename=title"},
exitCode: 0,
output: `# Success: normalise info texts
The normalise command with ` + "`" + `-t filename=title` + "`" + ` transform argument should remove and ` + "`" + `no_value` + "`" + ` and ` + "`" + `key=value` + "`" + ` args and replace ` + "`" + `filename` + "`" + ` key with ` + "`" + `title` + "`" + `,
` + "```" + `sh title=true.sh
exit 0
` + "```" + `
`,
},
} {
test := test
t.Run(test.testPath, func(t *testing.T) {
dir, err := os.MkdirTemp("", "example")
if err != nil {
t.Errorf("Failed to create temp dir: %v", err)
}
defer os.RemoveAll(dir)

var args []string
args = append(args, "normalise", "-o", dir)
args = append(args, test.transformsArgs...)
args = append(args, test.testPath)
rootCmd.SetArgs(args)

exitCode := Execute()
assert.Equal(t, test.exitCode, exitCode)

outputFile := filepath.Join(dir, filepath.Base(test.testPath))
assert.FileExists(t, outputFile)

outputBytes, err := os.ReadFile(filepath.Join(dir, filepath.Base(test.testPath)))
if err != nil {
t.Errorf("Failed to read output file: %v", err)
}
assert.Equal(t, test.output, string(outputBytes))
})
}
}
36 changes: 36 additions & 0 deletions cmd/normalise.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package cmd

import (
"github.com/UpCloudLtd/mdtest/utils"
"github.com/spf13/cobra"
)

var (
transforms []string
outputPath string

normaliseCmd = &cobra.Command{
Aliases: []string{"normalize"},
Use: "normalise",
Short: "Normalise the fenced code block info texts",
Long: "Normalise the fenced code block info texts. By default, removes all info texts defined after the language identifier from the starting code-block fence.",
Args: cobra.MinimumNArgs(1),
}
)

func init() {
rootCmd.AddCommand(normaliseCmd)
normaliseCmd.Flags().StringArrayVarP(&transforms, "transform", "t", nil, "transform info text key in `old=new` format, e.g., `-t filename=title` would transform `filename` info text to `title` info text")
normaliseCmd.Flags().StringVarP(&outputPath, "output", "o", "", "`directory` where to save the normalised files")
_ = normaliseCmd.MarkFlagRequired("output")
normaliseCmd.RunE = func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true

params := utils.NormalizeParameters{
OutputPath: outputPath,
Transforms: transforms,
}

return utils.Normalize(args, params)
}
}
24 changes: 3 additions & 21 deletions testcase/teststep.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"bufio"
"fmt"
"strings"

"github.com/UpCloudLtd/mdtest/utils"
)

type StepResult struct {
Expand All @@ -16,26 +18,6 @@ type Step interface {
Execute(*testStatus) StepResult
}

func parseOptions(optionsStr string) (string, map[string]string) {
optionsList := strings.Split(optionsStr, " ")
options := make(map[string]string)

lang := optionsList[0]
for _, option := range optionsList[1:] {
items := strings.SplitN(option, "=", 2)

key := items[0]
value := ""
if len(items) > 1 {
value = items[1]
}

options[key] = value
}

return lang, options
}

func parseCodeBlock(lang string, options map[string]string, content string) (Step, error) {
if options["filename"] != "" {
return parseFilenameStep(options, content)
Expand All @@ -57,7 +39,7 @@ func parseStep(scanner *bufio.Scanner) (Step, error) {
return nil, fmt.Errorf("current scanner position is not at start of a test step")
}

lang, options := parseOptions(line[3:])
lang, options := utils.ParseOptions(line[3:])

content := ""
for scanner.Scan() {
Expand Down
7 changes: 7 additions & 0 deletions testdata/success_normalise_infotexts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Success: normalise info texts

The normalise command with `-t filename=title` transform argument should remove and `no_value` and `key=value` args and replace `filename` key with `title`,

```sh no_value key=value filename=true.sh
exit 0
```
58 changes: 2 additions & 56 deletions testrun/testrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@ package testrun
import (
"fmt"
"io"
"os"
"path"
"strings"
"time"

"github.com/UpCloudLtd/mdtest/id"
"github.com/UpCloudLtd/mdtest/output"
"github.com/UpCloudLtd/mdtest/testcase"
"github.com/UpCloudLtd/mdtest/utils"
"github.com/UpCloudLtd/progress"
"github.com/UpCloudLtd/progress/messages"
)

type RunParameters struct {
Expand All @@ -30,57 +27,6 @@ type RunResult struct {
TestResults []testcase.TestResult
}

type PathWarning struct {
path string
err error
}

func (warn PathWarning) Message() messages.Update {
return messages.Update{
Message: fmt.Sprintf("Finding %s", warn.path),
Details: fmt.Sprintf("Error: %s", warn.err.Error()),
Status: messages.MessageStatusWarning,
}
}

func parseFilePaths(rawPaths []string, depth int) ([]string, []PathWarning) {
paths := []string{}
warnings := []PathWarning{}
for _, rawPath := range rawPaths {
info, err := os.Stat(rawPath)
if err != nil {
warnings = append(warnings, PathWarning{rawPath, err})
if info == nil {
continue
}
}

if info.Mode().IsDir() && depth != 0 {
files, err := os.ReadDir(rawPath)
if err != nil {
warnings = append(warnings, PathWarning{rawPath, err})
}

dirRawPaths := []string{}
for _, file := range files {
dirRawPaths = append(dirRawPaths, path.Join(rawPath, file.Name()))
}

dirPaths, dirWarnings := parseFilePaths(dirRawPaths, depth-1)
if dirWarnings != nil {
warnings = append(warnings, dirWarnings...)
}

paths = append(paths, dirPaths...)
}

if strings.HasSuffix(rawPath, ".md") {
paths = append(paths, rawPath)
}
}
return paths, warnings
}

func PrintSummary(target io.Writer, run RunResult) {
tests := output.Total(len(run.TestResults))
if run.SuccessCount > 0 {
Expand All @@ -102,7 +48,7 @@ func PrintSummary(target io.Writer, run RunResult) {

func Execute(rawPaths []string, params RunParameters) RunResult {
started := time.Now()
paths, warnings := parseFilePaths(rawPaths, 1)
paths, warnings := utils.ParseFilePaths(rawPaths, 1)

testLog := progress.NewProgress(nil)
testLog.Start()
Expand Down
81 changes: 81 additions & 0 deletions utils/files.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package utils

import (
"fmt"
"os"
"path"
"strings"

"github.com/UpCloudLtd/progress/messages"
)

type PathWarning struct {
path string
err error
}

func (warn PathWarning) Message() messages.Update {
return messages.Update{
Message: fmt.Sprintf("Finding %s", warn.path),
Details: fmt.Sprintf("Error: %s", warn.err.Error()),
Status: messages.MessageStatusWarning,
}
}

func ParseFilePaths(rawPaths []string, depth int) ([]string, []PathWarning) {
paths := []string{}
warnings := []PathWarning{}
for _, rawPath := range rawPaths {
info, err := os.Stat(rawPath)
if err != nil {
warnings = append(warnings, PathWarning{rawPath, err})
if info == nil {
continue
}
}

if info.Mode().IsDir() && depth != 0 {
files, err := os.ReadDir(rawPath)
if err != nil {
warnings = append(warnings, PathWarning{rawPath, err})
}

dirRawPaths := []string{}
for _, file := range files {
dirRawPaths = append(dirRawPaths, path.Join(rawPath, file.Name()))
}

dirPaths, dirWarnings := ParseFilePaths(dirRawPaths, depth-1)
if dirWarnings != nil {
warnings = append(warnings, dirWarnings...)
}

paths = append(paths, dirPaths...)
}

if strings.HasSuffix(rawPath, ".md") {
paths = append(paths, rawPath)
}
}
return paths, warnings
}

func ParseOptions(optionsStr string) (string, map[string]string) {
optionsList := strings.Split(optionsStr, " ")
options := make(map[string]string)

lang := optionsList[0]
for _, option := range optionsList[1:] {
items := strings.SplitN(option, "=", 2)

key := items[0]
value := ""
if len(items) > 1 {
value = items[1]
}

options[key] = value
}

return lang, options
}
Loading

0 comments on commit fd65b96

Please sign in to comment.