Skip to content

Commit

Permalink
Merge pull request #67 from ms-henglu/branch-230831-armstrong-arm-review
Browse files Browse the repository at this point in the history
Branch 230831 armstrong arm review
  • Loading branch information
ms-zhenhua authored Sep 18, 2023
2 parents 9f271ee + 4df9278 commit c4423d4
Show file tree
Hide file tree
Showing 979 changed files with 119,737 additions and 4,642 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## V0.12.0
FEATURES:
- Generate multiple test cases from one or multiple swagger spec files.
- Support using verified azapi examples as automatically generated dependencies.
- Support `azapi_resource_id` data source as automatically generated dependencies.

## v0.11.0
FEATURES:
- Support coverage report
Expand Down
110 changes: 110 additions & 0 deletions autorest/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package autorest

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

"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/ast"
"github.com/gomarkdown/markdown/parser"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
)

type Package struct {
Tag string
InputFiles []string
}

type YamlPackage struct {
InputFiles []string `yaml:"input-file"`
}

var r = regexp.MustCompile(`\$\(tag\)\s+==\s+'(.+)'`)

func ParseAutoRestConfig(filename string) []Package {
data, err := os.ReadFile(filename)
if err != nil {
return nil
}
md := markdown.Parse(data, parser.NewWithExtensions(parser.NoExtensions))
codeBlocks := allCodeBlocks(&md)

out := make([]Package, 0)
for _, codeBlock := range codeBlocks {
if string(codeBlock.Info) == "yaml" {
yamlPackage, err := ParseYamlConfig(string(codeBlock.Literal))
if err != nil {
logrus.Warnf("failed to parse yaml config: %+v", err)
} else {
for i, inputFile := range yamlPackage.InputFiles {
yamlPackage.InputFiles[i] = path.Clean(path.Join(path.Dir(filename), inputFile))
}
out = append(out, *yamlPackage)
}
}
}

return out
}

func allCodeBlocks(node *ast.Node) []ast.CodeBlock {
if node == nil {
return nil
}
switch v := (*node).(type) {
case *ast.Container:
out := make([]ast.CodeBlock, 0)
for _, child := range v.Children {
out = append(out, allCodeBlocks(&child)...)
}
return out
case *ast.Document:
out := make([]ast.CodeBlock, 0)
for _, child := range v.Children {
out = append(out, allCodeBlocks(&child)...)
}
return out
case *ast.Paragraph:
out := make([]ast.CodeBlock, 0)
for _, child := range v.Children {
out = append(out, allCodeBlocks(&child)...)
}
return out
case *ast.CodeBlock:
return []ast.CodeBlock{*v}
}
return nil
}

func ParseYamlConfig(content string) (*Package, error) {
matches := r.FindAllStringSubmatch(content, -1)
if len(matches) == 1 && len(matches[0]) == 2 {
tag := matches[0][1]

index := strings.Index(content, "\n")
if index == -1 {
return nil, fmt.Errorf("invalid yaml code block: no newline after tag, input: %v", content)
}

yamlContent := content[index+1:]
var yamlPackage YamlPackage
err := yaml.Unmarshal([]byte(yamlContent), &yamlPackage)
if err != nil {
return nil, err
}

if len(yamlPackage.InputFiles) == 0 {
return nil, fmt.Errorf("input-file is empty, input: %v", content)
}

return &Package{
Tag: tag,
InputFiles: yamlPackage.InputFiles,
}, nil
}
return nil, fmt.Errorf("tag not found in yaml config: %s", content)
}
115 changes: 115 additions & 0 deletions autorest/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package autorest

import (
"log"
"os"
"path"
"testing"
)

func Test_ParseAutoRestConfig(t *testing.T) {
wd, _ := os.Getwd()
testcases := []struct {
Input string
Expected []Package
}{
{
Input: path.Join(wd, "testdata", "readme.md"),
Expected: []Package{
{
Tag: "package-2015-10",
},
{
Tag: "package-2017-05-preview",
},
{
Tag: "package-2018-01-preview",
},
{
Tag: "package-2018-06-preview",
},
{
Tag: "package-2019-06",
},
{
Tag: "package-2020-01-13-preview",
},
{
Tag: "package-2021-06-22",
},
{
Tag: "package-2022-01-31",
},
{
Tag: "package-2022-02-22",
},
{
Tag: "package-2022-08-08",
},
},
},
}

for _, testcase := range testcases {
log.Printf("[DEBUG] testcase: %+v", testcase.Input)
actual := ParseAutoRestConfig(testcase.Input)
if len(actual) != len(testcase.Expected) {
t.Errorf("expected %d packages, got %d", len(testcase.Expected), len(actual))
}
for i := range actual {
if actual[i].Tag != testcase.Expected[i].Tag {
t.Errorf("expected %s, got %s", testcase.Expected[i].Tag, actual[i].Tag)
}
if len(actual[i].InputFiles) == 0 {
t.Errorf("expected non-empty input files")
}
}
}
}

func Test_ParseYamlConfig(t *testing.T) {
testcases := []struct {
Input string
Expected *Package
ExpectError bool
}{
{
Input: `$(tag) == 'package-2015-10'
input-file:
- Microsoft.Automation/stable/2015-10-31/account.json
- Microsoft.Automation/stable/2015-10-31/certificate.json
`,
Expected: &Package{
Tag: "package-2015-10",
InputFiles: []string{
"Microsoft.Automation/stable/2015-10-31/account.json",
"Microsoft.Automation/stable/2015-10-31/certificate.json",
},
},
ExpectError: false,
},
}

for _, testcase := range testcases {
log.Printf("[DEBUG] testcase: %+v", testcase.Input)

actual, err := ParseYamlConfig(testcase.Input)
if testcase.ExpectError != (err != nil) {
t.Errorf("expected error %v, got %v", testcase.ExpectError, err)
continue
}
if actual.Tag != testcase.Expected.Tag {
t.Errorf("expected %s, got %s", testcase.Expected.Tag, actual.Tag)
}
if len(actual.InputFiles) != len(testcase.Expected.InputFiles) {
t.Errorf("expected %d input files, got %d", len(testcase.Expected.InputFiles), len(actual.InputFiles))
continue
}
for i := range actual.InputFiles {
if actual.InputFiles[i] != testcase.Expected.InputFiles[i] {
t.Errorf("expected %s, got %s", testcase.Expected.InputFiles[i], actual.InputFiles[i])
}
}
}

}
Loading

0 comments on commit c4423d4

Please sign in to comment.