From 311748a97d4e6439d4c3c87269d7d9b795ada5f2 Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Mon, 30 Oct 2023 15:32:35 +0100 Subject: [PATCH 01/12] move flags out of main function --- schema.go | 77 ++++++++++++++++++++++++++++++++++---------------- schema_test.go | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 24 deletions(-) diff --git a/schema.go b/schema.go index 736eaf4..984df2e 100644 --- a/schema.go +++ b/schema.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "encoding/json" "errors" "flag" @@ -12,6 +13,15 @@ import ( "gopkg.in/yaml.v3" ) +// Save values of parsed flags in Config +type Config struct { + input multiStringFlag + outputPath string + draft int + + args []string +} + // Define a custom flag type to accept multiple yamlFiles type multiStringFlag []string @@ -27,6 +37,7 @@ func (m *multiStringFlag) Set(value string) error { return nil } +// Read and unmarshal YAML file func readAndUnmarshalYAML(filePath string, target interface{}) error { data, err := os.ReadFile(filePath) if err != nil { @@ -35,6 +46,7 @@ func readAndUnmarshalYAML(filePath string, target interface{}) error { return yaml.Unmarshal(data, target) } +// Merge all YAML files into a single map func mergeMaps(a, b map[string]interface{}) map[string]interface{} { out := make(map[string]interface{}, len(a)) for k, v := range a { @@ -54,6 +66,7 @@ func mergeMaps(a, b map[string]interface{}) map[string]interface{} { return out } +// Print the merged map to a file as JSON schema func printMap(data *jsonschema.Document, outputPath string) error { if data == nil { return errors.New("data is nil") @@ -82,35 +95,39 @@ func printMap(data *jsonschema.Document, outputPath string) error { return nil } -func usage() { - fmt.Fprintln(os.Stderr, "usage: helm schema [-input STR] [-draft INT] [-output STR]") - flag.PrintDefaults() -} +// Parse flags +func parseFlags(progname string, args []string) (config *Config, output string, err error) { + flags := flag.NewFlagSet(progname, flag.ContinueOnError) + var buf bytes.Buffer + flags.SetOutput(&buf) -func main() { - // Define the custom flag for yamlFiles and set its default value - var yamlFiles multiStringFlag - flag.Var(&yamlFiles, "input", "Multiple yamlFiles as inputs (comma-separated)") + var conf Config + flags.Var(&conf.input, "input", "Multiple yaml files as inputs (comma-separated)") + flags.StringVar(&conf.outputPath, "output", "values.schema.json", "Output file path") + flags.IntVar(&conf.draft, "draft", 2020, "Draft version (4, 6, 7, 2019, or 2020)") - // Define the flag to specify the schema url - draft := flag.Int("draft", 2020, "Draft version (4, 6, 7, 2019, or 2020)") + err = flags.Parse(args) + if err != nil { + fmt.Fprintln(os.Stderr, "usage: helm schema [-input STR] [-draft INT] [-output STR]") + return nil, buf.String(), err + } - // Define the flag to specify the output file - var outputPath string - flag.StringVar(&outputPath, "output", "values.schema.json", "Output file path") + conf.args = flags.Args() + return &conf, buf.String(), nil +} - flag.Usage = usage - flag.Parse() +// Generate JSON schema +func generateJsonSchema(config *Config) { + fmt.Printf("config = %+v\n", *config) // Check if the input flag is set - if len(yamlFiles) == 0 { - fmt.Println("Input flag is required. Please provide input yaml files using the -input flag.") - usage() + if len(config.input) == 0 { + fmt.Fprintln(os.Stderr, "Input flag is required. Please provide input yaml files using the -input flag.") return } var schemaUrl string - switch *draft { + switch config.draft { case 4: schemaUrl = "http://json-schema.org/draft-04/schema#" case 6: @@ -130,8 +147,7 @@ func main() { mergedMap := make(map[string]interface{}) // Iterate over the input YAML files - for _, filePath := range yamlFiles { - // Read and unmarshal each YAML file + for _, filePath := range config.input { var currentMap map[string]interface{} if err := readAndUnmarshalYAML(filePath, ¤tMap); err != nil { fmt.Printf("Error reading %s: %v\n", filePath, err) @@ -140,15 +156,28 @@ func main() { // Merge the current YAML data with the mergedMap mergedMap = mergeMaps(mergedMap, currentMap) - // fmt.Println(mergedMap) } - // Print or save the merged map + // Print the merged map d := jsonschema.NewDocument(schemaUrl) d.ReadDeep(&mergedMap) - err := printMap(d, outputPath) + err := printMap(d, config.outputPath) if err != nil { fmt.Printf("Error: %v\n", err) } } + +func main() { + conf, output, err := parseFlags(os.Args[0], os.Args[1:]) + if err == flag.ErrHelp { + fmt.Println("output:", output) + os.Exit(2) + } else if err != nil { + fmt.Println("got error:", err) + fmt.Println("output:\n", output) + os.Exit(1) + } + + generateJsonSchema(conf) +} diff --git a/schema_test.go b/schema_test.go index 46b69b5..6a25b7c 100644 --- a/schema_test.go +++ b/schema_test.go @@ -1,8 +1,10 @@ package main import ( + "flag" "os" "reflect" + "strings" "testing" "github.com/losisin/go-jsonschema-generator" @@ -206,3 +208,78 @@ func TestPrintMap(t *testing.T) { }) } } + +func TestParseFlagsCorrect(t *testing.T) { + var tests = []struct { + args []string + conf Config + }{ + {[]string{"-input", "testdata/values.yaml"}, + Config{input: multiStringFlag{"testdata/values.yaml"}, outputPath: "values.schema.json", draft: 2020, args: []string{}}}, + + {[]string{"-input", "values1.yaml testdata/values.yaml"}, + Config{input: multiStringFlag{"values1.yaml testdata/values.yaml"}, outputPath: "values.schema.json", draft: 2020, args: []string{}}}, + + {[]string{"-input", "testdata/values.yaml", "-output", "my.schema.json", "-draft", "2019"}, + Config{input: multiStringFlag{"testdata/values.yaml"}, outputPath: "my.schema.json", draft: 2019, args: []string{}}}, + } + + for _, tt := range tests { + t.Run(strings.Join(tt.args, " "), func(t *testing.T) { + conf, output, err := parseFlags("prog", tt.args) + if err != nil { + t.Errorf("err got %v, want nil", err) + } + if output != "" { + t.Errorf("output got %q, want empty", output) + } + if !reflect.DeepEqual(*conf, tt.conf) { + t.Errorf("conf got %+v, want %+v", *conf, tt.conf) + } + }) + } +} + +func TestParseFlagsUsage(t *testing.T) { + var usageArgs = []string{"-help", "-h", "--help"} + + for _, arg := range usageArgs { + t.Run(arg, func(t *testing.T) { + conf, output, err := parseFlags("prog", []string{arg}) + if err != flag.ErrHelp { + t.Errorf("err got %v, want ErrHelp", err) + } + if conf != nil { + t.Errorf("conf got %v, want nil", conf) + } + if !strings.Contains(output, "Usage of") { + t.Errorf("output can't find \"Usage of\": %q", output) + } + }) + } +} + +func TestParseFlagsError(t *testing.T) { + var tests = []struct { + args []string + errstr string + }{ + {[]string{"-input"}, "flag needs an argument"}, + {[]string{"-draft", "foo"}, "invalid value"}, + } + + for _, tt := range tests { + t.Run(strings.Join(tt.args, " "), func(t *testing.T) { + conf, output, err := parseFlags("prog", tt.args) + if conf != nil { + t.Errorf("conf got %v, want nil", conf) + } + if !strings.Contains(err.Error(), tt.errstr) { + t.Errorf("err got %q, want to find %q", err.Error(), tt.errstr) + } + if !strings.Contains(output, "Usage of") { + t.Errorf("output got %q", output) + } + }) + } +} From 6563be221f205448d93c5618528dd7ea3e2c3caa Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Mon, 30 Oct 2023 17:02:21 +0100 Subject: [PATCH 02/12] fix -help flag --- schema.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/schema.go b/schema.go index 984df2e..eb66e4a 100644 --- a/schema.go +++ b/schema.go @@ -106,9 +106,14 @@ func parseFlags(progname string, args []string) (config *Config, output string, flags.StringVar(&conf.outputPath, "output", "values.schema.json", "Output file path") flags.IntVar(&conf.draft, "draft", 2020, "Draft version (4, 6, 7, 2019, or 2020)") + // flags.Usage = func() { + // fmt.Println("usage: helm schema [-input STR] [-draft INT] [-output STR]") + // flags.PrintDefaults() + // } + err = flags.Parse(args) if err != nil { - fmt.Fprintln(os.Stderr, "usage: helm schema [-input STR] [-draft INT] [-output STR]") + fmt.Println("usage: helm schema [-input STR] [-draft INT] [-output STR]") return nil, buf.String(), err } @@ -171,8 +176,8 @@ func generateJsonSchema(config *Config) { func main() { conf, output, err := parseFlags(os.Args[0], os.Args[1:]) if err == flag.ErrHelp { - fmt.Println("output:", output) - os.Exit(2) + fmt.Println(output) + os.Exit(0) } else if err != nil { fmt.Println("got error:", err) fmt.Println("output:\n", output) From 9bc18490641857a34697fde6b4b84ed5cec92e3f Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Mon, 30 Oct 2023 22:33:30 +0100 Subject: [PATCH 03/12] add test data --- schema.go | 5 ----- testdata/{values.yaml => values_1.yaml} | 0 testdata/values_2.yaml | 16 ++++++++++++++++ testdata/values_3.yaml | 6 ++++++ 4 files changed, 22 insertions(+), 5 deletions(-) rename testdata/{values.yaml => values_1.yaml} (100%) create mode 100644 testdata/values_2.yaml create mode 100644 testdata/values_3.yaml diff --git a/schema.go b/schema.go index eb66e4a..b3721da 100644 --- a/schema.go +++ b/schema.go @@ -106,11 +106,6 @@ func parseFlags(progname string, args []string) (config *Config, output string, flags.StringVar(&conf.outputPath, "output", "values.schema.json", "Output file path") flags.IntVar(&conf.draft, "draft", 2020, "Draft version (4, 6, 7, 2019, or 2020)") - // flags.Usage = func() { - // fmt.Println("usage: helm schema [-input STR] [-draft INT] [-output STR]") - // flags.PrintDefaults() - // } - err = flags.Parse(args) if err != nil { fmt.Println("usage: helm schema [-input STR] [-draft INT] [-output STR]") diff --git a/testdata/values.yaml b/testdata/values_1.yaml similarity index 100% rename from testdata/values.yaml rename to testdata/values_1.yaml diff --git a/testdata/values_2.yaml b/testdata/values_2.yaml new file mode 100644 index 0000000..5803757 --- /dev/null +++ b/testdata/values_2.yaml @@ -0,0 +1,16 @@ +nodeSelector: + kubernetes.io/hostname: "" +deep: + deep1: + deep2: + deep3: + deep4: "qwerty" +list: + - "a" + - "b" + - "c" + +key1: "qwerty" +key2: 42 +key3: {} +key4: [] diff --git a/testdata/values_3.yaml b/testdata/values_3.yaml new file mode 100644 index 0000000..e01ec5e --- /dev/null +++ b/testdata/values_3.yaml @@ -0,0 +1,6 @@ +this: +is: +not valid: +this: +is: +not valid: \ No newline at end of file From f298b49e0e324fd4ea021a098379b368f8c89c47 Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Mon, 30 Oct 2023 22:34:07 +0100 Subject: [PATCH 04/12] add some uni tests Signed-off-by: Aleksandar Stojanov --- schema_test.go | 91 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 16 deletions(-) diff --git a/schema_test.go b/schema_test.go index 6a25b7c..997f04c 100644 --- a/schema_test.go +++ b/schema_test.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" "os" "reflect" "strings" @@ -107,7 +108,6 @@ func TestReadAndUnmarshalYAML(t *testing.T) { }) t.Run("File Missing", func(t *testing.T) { - // YAML file is assumed to be missing missingFilePath := "missing.yaml" var target map[string]interface{} @@ -178,15 +178,14 @@ func TestPrintMap(t *testing.T) { var yamlData map[string]interface{} - // Test successful data read and schema creation - err := readAndUnmarshalYAML("testdata/values.yaml", &yamlData) + err := readAndUnmarshalYAML("testdata/values_1.yaml", &yamlData) if err != nil { t.Fatalf("Failed to mock YAML data: %v", err) } data := jsonschema.NewDocument("") data.ReadDeep(&yamlData) - cases := []struct { + tests := []struct { data *jsonschema.Document tmpFile string expectError bool @@ -196,32 +195,32 @@ func TestPrintMap(t *testing.T) { {nil, tmpFile, true}, } - for _, c := range cases { + for _, tt := range tests { t.Run("PrintMap", func(t *testing.T) { - err := printMap(c.data, c.tmpFile) + err := printMap(tt.data, tt.tmpFile) switch { - case err == nil && c.expectError: + case err == nil && tt.expectError: t.Fatalf("Expected an error, but printMap succeeded") - case err != nil && !c.expectError: + case err != nil && !tt.expectError: t.Fatalf("Unexpected error: %v", err) } }) } } -func TestParseFlagsCorrect(t *testing.T) { +func TestParseFlagsPass(t *testing.T) { var tests = []struct { args []string conf Config }{ - {[]string{"-input", "testdata/values.yaml"}, - Config{input: multiStringFlag{"testdata/values.yaml"}, outputPath: "values.schema.json", draft: 2020, args: []string{}}}, + {[]string{"-input", "testdata/values_1.yaml"}, + Config{input: multiStringFlag{"testdata/values_1.yaml"}, outputPath: "values.schema.json", draft: 2020, args: []string{}}}, - {[]string{"-input", "values1.yaml testdata/values.yaml"}, - Config{input: multiStringFlag{"values1.yaml testdata/values.yaml"}, outputPath: "values.schema.json", draft: 2020, args: []string{}}}, + {[]string{"-input", "values1.yaml testdata/values_1.yaml"}, + Config{input: multiStringFlag{"values1.yaml testdata/values_1.yaml"}, outputPath: "values.schema.json", draft: 2020, args: []string{}}}, - {[]string{"-input", "testdata/values.yaml", "-output", "my.schema.json", "-draft", "2019"}, - Config{input: multiStringFlag{"testdata/values.yaml"}, outputPath: "my.schema.json", draft: 2019, args: []string{}}}, + {[]string{"-input", "testdata/values_1.yaml", "-output", "my.schema.json", "-draft", "2019"}, + Config{input: multiStringFlag{"testdata/values_1.yaml"}, outputPath: "my.schema.json", draft: 2019, args: []string{}}}, } for _, tt := range tests { @@ -259,7 +258,7 @@ func TestParseFlagsUsage(t *testing.T) { } } -func TestParseFlagsError(t *testing.T) { +func TestParseFlagsFail(t *testing.T) { var tests = []struct { args []string errstr string @@ -283,3 +282,63 @@ func TestParseFlagsError(t *testing.T) { }) } } + +func TestGenerateJsonSchemaPass(t *testing.T) { + var tests = []struct { + conf Config + expectedUrl string + }{ + {Config{input: multiStringFlag{"testdata/values_1.yaml testdata/values_2.yaml"}, draft: 2020, outputPath: "2020.schema.json", args: []string{}}, "https://json-schema.org/draft/2020-12/schema"}, + {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 2020, outputPath: "2020.schema.json", args: []string{}}, "https://json-schema.org/draft/2020-12/schema"}, + {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 2019, outputPath: "2019.schema.json", args: []string{}}, "https://json-schema.org/draft/2019-09/schema"}, + {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 7, outputPath: "7.schema.json", args: []string{}}, "http://json-schema.org/draft-07/schema#"}, + {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 6, outputPath: "6.schema.json", args: []string{}}, "http://json-schema.org/draft-06/schema#"}, + {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 4, outputPath: "4.schema.json", args: []string{}}, "http://json-schema.org/draft-04/schema#"}, + } + + for _, tt := range tests { + t.Run(fmt.Sprintf("%v", tt.conf), func(t *testing.T) { + conf := &tt.conf + generateJsonSchema(conf) + + _, err := os.Stat(conf.outputPath) + if os.IsNotExist(err) { + t.Errorf("Expected file '%q' to be created, but it doesn't exist", conf.outputPath) + } + os.Remove(conf.outputPath) + }) + t.Run(fmt.Sprintf("%v", tt.conf), func(t *testing.T) { + conf := &tt.conf + generateJsonSchema(conf) + + outputJson, err := os.ReadFile(conf.outputPath) + if err != nil { + t.Errorf("Error reading file '%q': %v", conf.outputPath, err) + } + + actualURL := string(outputJson) + if !strings.Contains(actualURL, tt.expectedUrl) { + t.Errorf("Schema URL does not match. Got: %s, Expected: %s", actualURL, tt.expectedUrl) + } + os.Remove(conf.outputPath) + }) + } +} + +// func TestGenerateJsonSchemaFail(t *testing.T) { +// var tests = []struct { +// conf Config +// }{ +// {Config{input: multiStringFlag{}, draft: 2020, outputPath: "2020.schema.json", args: []string{}}}, +// {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 0, outputPath: "0.schema.json", args: []string{}}}, +// {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 0, outputPath: "", args: []string{}}}, +// } + +// for _, tt := range tests { +// t.Run(fmt.Sprintf("%v", tt.conf), func(t *testing.T) { +// conf := &tt.conf +// generateJsonSchema(conf) + +// }) +// } +// } From 2f2b515045726c8e7205c8525bd5af320b00c8af Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Mon, 30 Oct 2023 22:45:47 +0100 Subject: [PATCH 05/12] test codecov options Signed-off-by: Aleksandar Stojanov --- codecov.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/codecov.yml b/codecov.yml index ba6f0b2..2d57c35 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,2 +1,5 @@ +coverage: + precision: 3 + range: "70...100" comment: require_changes: true From 4f5ef5dc46f15bfbc45756babe92e3a85b62ed7e Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Mon, 30 Oct 2023 22:56:04 +0100 Subject: [PATCH 06/12] config codecov Signed-off-by: Aleksandar Stojanov --- codecov.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/codecov.yml b/codecov.yml index 2d57c35..11d4fdd 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,5 +1,6 @@ coverage: - precision: 3 - range: "70...100" + precision: 2 + round: nearest + range: 50...75 comment: require_changes: true From df67f00cb9040e61c4de3ebe2213697725d4291e Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Mon, 30 Oct 2023 23:37:56 +0100 Subject: [PATCH 07/12] cleanup a bit Signed-off-by: Aleksandar Stojanov --- schema.go | 2 -- schema_test.go | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/schema.go b/schema.go index b3721da..901dfc1 100644 --- a/schema.go +++ b/schema.go @@ -118,8 +118,6 @@ func parseFlags(progname string, args []string) (config *Config, output string, // Generate JSON schema func generateJsonSchema(config *Config) { - fmt.Printf("config = %+v\n", *config) - // Check if the input flag is set if len(config.input) == 0 { fmt.Fprintln(os.Stderr, "Input flag is required. Please provide input yaml files using the -input flag.") diff --git a/schema_test.go b/schema_test.go index 997f04c..5854732 100644 --- a/schema_test.go +++ b/schema_test.go @@ -261,7 +261,7 @@ func TestParseFlagsUsage(t *testing.T) { func TestParseFlagsFail(t *testing.T) { var tests = []struct { args []string - errstr string + errStr string }{ {[]string{"-input"}, "flag needs an argument"}, {[]string{"-draft", "foo"}, "invalid value"}, @@ -273,8 +273,8 @@ func TestParseFlagsFail(t *testing.T) { if conf != nil { t.Errorf("conf got %v, want nil", conf) } - if !strings.Contains(err.Error(), tt.errstr) { - t.Errorf("err got %q, want to find %q", err.Error(), tt.errstr) + if !strings.Contains(err.Error(), tt.errStr) { + t.Errorf("err got %q, want to find %q", err.Error(), tt.errStr) } if !strings.Contains(output, "Usage of") { t.Errorf("output got %q", output) From 621f33ac11b2c1990ac5338e5aa8badc65bfbded Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Mon, 30 Oct 2023 23:51:33 +0100 Subject: [PATCH 08/12] enough for today --- schema_test.go | 56 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/schema_test.go b/schema_test.go index 5854732..3b70411 100644 --- a/schema_test.go +++ b/schema_test.go @@ -1,8 +1,10 @@ package main import ( + "bytes" "flag" "fmt" + "log" "os" "reflect" "strings" @@ -325,20 +327,40 @@ func TestGenerateJsonSchemaPass(t *testing.T) { } } -// func TestGenerateJsonSchemaFail(t *testing.T) { -// var tests = []struct { -// conf Config -// }{ -// {Config{input: multiStringFlag{}, draft: 2020, outputPath: "2020.schema.json", args: []string{}}}, -// {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 0, outputPath: "0.schema.json", args: []string{}}}, -// {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 0, outputPath: "", args: []string{}}}, -// } - -// for _, tt := range tests { -// t.Run(fmt.Sprintf("%v", tt.conf), func(t *testing.T) { -// conf := &tt.conf -// generateJsonSchema(conf) - -// }) -// } -// } +func captureOutput(f func()) string { + var buf bytes.Buffer + log.SetOutput(&buf) + f() + log.SetOutput(os.Stderr) + return buf.String() +} + +func TestGenerateJsonSchemaFail(t *testing.T) { + var tests = []struct { + conf Config + errStr string + }{ + {Config{input: multiStringFlag{}, draft: 2020, outputPath: "2020.schema.json", args: []string{}}, "Input flag is required"}, + {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 1903, outputPath: "values.schema.json", args: []string{}}, "Invalid draft version"}, + } + + for _, tt := range tests { + t.Run(fmt.Sprintf("%v", tt.conf), func(t *testing.T) { + conf := &tt.conf + generateJsonSchema(conf) + + want := tt.errStr + got := captureOutput(func() { + cui.Success(tt.args.message) + }) + got := err + if got.Error() != want { + t.Error("Got:", got, ",", "Want:", want) + } + + // if strings.Contains(capturedOutput, tt.errStr) { + // t.Errorf("err got %q, want to find %q", capturedOutput, tt.errStr) + // } + }) + } +} From 94f08f50cba38a52ca3793cb312b2ea613abeb98 Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Mon, 30 Oct 2023 23:51:50 +0100 Subject: [PATCH 09/12] enough for today Signed-off-by: Aleksandar Stojanov --- schema_test.go | 58 +++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/schema_test.go b/schema_test.go index 3b70411..3abb0ac 100644 --- a/schema_test.go +++ b/schema_test.go @@ -335,32 +335,32 @@ func captureOutput(f func()) string { return buf.String() } -func TestGenerateJsonSchemaFail(t *testing.T) { - var tests = []struct { - conf Config - errStr string - }{ - {Config{input: multiStringFlag{}, draft: 2020, outputPath: "2020.schema.json", args: []string{}}, "Input flag is required"}, - {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 1903, outputPath: "values.schema.json", args: []string{}}, "Invalid draft version"}, - } - - for _, tt := range tests { - t.Run(fmt.Sprintf("%v", tt.conf), func(t *testing.T) { - conf := &tt.conf - generateJsonSchema(conf) - - want := tt.errStr - got := captureOutput(func() { - cui.Success(tt.args.message) - }) - got := err - if got.Error() != want { - t.Error("Got:", got, ",", "Want:", want) - } - - // if strings.Contains(capturedOutput, tt.errStr) { - // t.Errorf("err got %q, want to find %q", capturedOutput, tt.errStr) - // } - }) - } -} +// func TestGenerateJsonSchemaFail(t *testing.T) { +// var tests = []struct { +// conf Config +// errStr string +// }{ +// {Config{input: multiStringFlag{}, draft: 2020, outputPath: "2020.schema.json", args: []string{}}, "Input flag is required"}, +// {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 1903, outputPath: "values.schema.json", args: []string{}}, "Invalid draft version"}, +// } + +// for _, tt := range tests { +// t.Run(fmt.Sprintf("%v", tt.conf), func(t *testing.T) { +// conf := &tt.conf +// generateJsonSchema(conf) + +// want := tt.errStr +// got := captureOutput(func() { +// cui.Success(tt.args.message) +// }) +// got := err +// if got.Error() != want { +// t.Error("Got:", got, ",", "Want:", want) +// } + +// if strings.Contains(capturedOutput, tt.errStr) { +// t.Errorf("err got %q, want to find %q", capturedOutput, tt.errStr) +// } +// }) +// } +// } From 5ecfb373fa8aef66cbe97abcb4c39d2ef5912ddd Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Mon, 30 Oct 2023 23:53:06 +0100 Subject: [PATCH 10/12] fix lint errors Signed-off-by: Aleksandar Stojanov --- schema_test.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/schema_test.go b/schema_test.go index 3abb0ac..6ce6cbc 100644 --- a/schema_test.go +++ b/schema_test.go @@ -1,10 +1,8 @@ package main import ( - "bytes" "flag" "fmt" - "log" "os" "reflect" "strings" @@ -327,13 +325,13 @@ func TestGenerateJsonSchemaPass(t *testing.T) { } } -func captureOutput(f func()) string { - var buf bytes.Buffer - log.SetOutput(&buf) - f() - log.SetOutput(os.Stderr) - return buf.String() -} +// func captureOutput(f func()) string { +// var buf bytes.Buffer +// log.SetOutput(&buf) +// f() +// log.SetOutput(os.Stderr) +// return buf.String() +// } // func TestGenerateJsonSchemaFail(t *testing.T) { // var tests = []struct { From 83fc0327a54ce71dd1873f44118243e957922d90 Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Thu, 2 Nov 2023 17:45:32 +0100 Subject: [PATCH 11/12] add more unit tests Signed-off-by: Aleksandar Stojanov --- schema.go | 6 ++++-- schema_test.go | 52 +++++++++++++------------------------------------- 2 files changed, 17 insertions(+), 41 deletions(-) diff --git a/schema.go b/schema.go index 901dfc1..3339940 100644 --- a/schema.go +++ b/schema.go @@ -117,11 +117,11 @@ func parseFlags(progname string, args []string) (config *Config, output string, } // Generate JSON schema -func generateJsonSchema(config *Config) { +func generateJsonSchema(config *Config) error { // Check if the input flag is set if len(config.input) == 0 { fmt.Fprintln(os.Stderr, "Input flag is required. Please provide input yaml files using the -input flag.") - return + return nil } var schemaUrl string @@ -164,6 +164,8 @@ func generateJsonSchema(config *Config) { if err != nil { fmt.Printf("Error: %v\n", err) } + + return nil } func main() { diff --git a/schema_test.go b/schema_test.go index 6ce6cbc..4b3c9f0 100644 --- a/schema_test.go +++ b/schema_test.go @@ -265,6 +265,7 @@ func TestParseFlagsFail(t *testing.T) { }{ {[]string{"-input"}, "flag needs an argument"}, {[]string{"-draft", "foo"}, "invalid value"}, + {[]string{"-foo"}, "flag provided but not defined"}, } for _, tt := range tests { @@ -288,7 +289,7 @@ func TestGenerateJsonSchemaPass(t *testing.T) { conf Config expectedUrl string }{ - {Config{input: multiStringFlag{"testdata/values_1.yaml testdata/values_2.yaml"}, draft: 2020, outputPath: "2020.schema.json", args: []string{}}, "https://json-schema.org/draft/2020-12/schema"}, + {Config{input: multiStringFlag{"testdata/values_1.yaml", "testdata/values_2.yaml"}, draft: 2020, outputPath: "2020.schema.json", args: []string{}}, "https://json-schema.org/draft/2020-12/schema"}, {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 2020, outputPath: "2020.schema.json", args: []string{}}, "https://json-schema.org/draft/2020-12/schema"}, {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 2019, outputPath: "2019.schema.json", args: []string{}}, "https://json-schema.org/draft/2019-09/schema"}, {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 7, outputPath: "7.schema.json", args: []string{}}, "http://json-schema.org/draft-07/schema#"}, @@ -305,6 +306,17 @@ func TestGenerateJsonSchemaPass(t *testing.T) { if os.IsNotExist(err) { t.Errorf("Expected file '%q' to be created, but it doesn't exist", conf.outputPath) } + + outputJson, err := os.ReadFile(conf.outputPath) + if err != nil { + t.Errorf("Error reading file '%q': %v", conf.outputPath, err) + } + + actualURL := string(outputJson) + if !strings.Contains(actualURL, tt.expectedUrl) { + t.Errorf("Schema URL does not match. Got: %s, Expected: %s", actualURL, tt.expectedUrl) + } + os.Remove(conf.outputPath) }) t.Run(fmt.Sprintf("%v", tt.conf), func(t *testing.T) { @@ -324,41 +336,3 @@ func TestGenerateJsonSchemaPass(t *testing.T) { }) } } - -// func captureOutput(f func()) string { -// var buf bytes.Buffer -// log.SetOutput(&buf) -// f() -// log.SetOutput(os.Stderr) -// return buf.String() -// } - -// func TestGenerateJsonSchemaFail(t *testing.T) { -// var tests = []struct { -// conf Config -// errStr string -// }{ -// {Config{input: multiStringFlag{}, draft: 2020, outputPath: "2020.schema.json", args: []string{}}, "Input flag is required"}, -// {Config{input: multiStringFlag{"testdata/values_1.yaml"}, draft: 1903, outputPath: "values.schema.json", args: []string{}}, "Invalid draft version"}, -// } - -// for _, tt := range tests { -// t.Run(fmt.Sprintf("%v", tt.conf), func(t *testing.T) { -// conf := &tt.conf -// generateJsonSchema(conf) - -// want := tt.errStr -// got := captureOutput(func() { -// cui.Success(tt.args.message) -// }) -// got := err -// if got.Error() != want { -// t.Error("Got:", got, ",", "Want:", want) -// } - -// if strings.Contains(capturedOutput, tt.errStr) { -// t.Errorf("err got %q, want to find %q", capturedOutput, tt.errStr) -// } -// }) -// } -// } From 77b40167bd34baea3301f63719da879f3dcf1daa Mon Sep 17 00:00:00 2001 From: Aleksandar Stojanov Date: Thu, 2 Nov 2023 17:53:24 +0100 Subject: [PATCH 12/12] fix golang lint errors Signed-off-by: Aleksandar Stojanov --- codecov.yml | 2 +- schema.go | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/codecov.yml b/codecov.yml index 11d4fdd..9f57ac0 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,6 +1,6 @@ coverage: precision: 2 round: nearest - range: 50...75 + range: 50...70 comment: require_changes: true diff --git a/schema.go b/schema.go index 3339940..fd151b8 100644 --- a/schema.go +++ b/schema.go @@ -117,11 +117,11 @@ func parseFlags(progname string, args []string) (config *Config, output string, } // Generate JSON schema -func generateJsonSchema(config *Config) error { +func generateJsonSchema(config *Config) { // Check if the input flag is set if len(config.input) == 0 { fmt.Fprintln(os.Stderr, "Input flag is required. Please provide input yaml files using the -input flag.") - return nil + os.Exit(2) } var schemaUrl string @@ -164,8 +164,6 @@ func generateJsonSchema(config *Config) error { if err != nil { fmt.Printf("Error: %v\n", err) } - - return nil } func main() {