diff --git a/commands_test.go b/commands_test.go index 2da034b9..250922c2 100644 --- a/commands_test.go +++ b/commands_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/spf13/cobra" + "github.com/mikefarah/yq/test" ) func getRootCommand() *cobra.Command { @@ -16,7 +17,7 @@ func getRootCommand() *cobra.Command { func TestRootCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "") + result := test.RunCmd(cmd, "") if result.Error != nil { t.Error(result.Error) } @@ -28,7 +29,7 @@ func TestRootCmd(t *testing.T) { func TestRootCmd_Help(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "--help") + result := test.RunCmd(cmd, "--help") if result.Error != nil { t.Error(result.Error) } @@ -40,7 +41,7 @@ func TestRootCmd_Help(t *testing.T) { func TestRootCmd_VerboseLong(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "--verbose") + result := test.RunCmd(cmd, "--verbose") if result.Error != nil { t.Error(result.Error) } @@ -52,7 +53,7 @@ func TestRootCmd_VerboseLong(t *testing.T) { func TestRootCmd_VerboseShort(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "-v") + result := test.RunCmd(cmd, "-v") if result.Error != nil { t.Error(result.Error) } @@ -64,7 +65,7 @@ func TestRootCmd_VerboseShort(t *testing.T) { func TestRootCmd_TrimLong(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "--trim") + result := test.RunCmd(cmd, "--trim") if result.Error != nil { t.Error(result.Error) } @@ -76,7 +77,7 @@ func TestRootCmd_TrimLong(t *testing.T) { func TestRootCmd_TrimShort(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "-t") + result := test.RunCmd(cmd, "-t") if result.Error != nil { t.Error(result.Error) } @@ -88,7 +89,7 @@ func TestRootCmd_TrimShort(t *testing.T) { func TestRootCmd_VersionShort(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "-V") + result := test.RunCmd(cmd, "-V") if result.Error != nil { t.Error(result.Error) } @@ -99,7 +100,7 @@ func TestRootCmd_VersionShort(t *testing.T) { func TestRootCmd_VersionLong(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "--version") + result := test.RunCmd(cmd, "--version") if result.Error != nil { t.Error(result.Error) } @@ -110,40 +111,40 @@ func TestRootCmd_VersionLong(t *testing.T) { func TestReadCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read examples/sample.yaml b.c") + result := test.RunCmd(cmd, "read examples/sample.yaml b.c") if result.Error != nil { t.Error(result.Error) } - assertResult(t, "2\n", result.Output) + test.AssertResult(t, "2\n", result.Output) } func TestReadInvalidDocumentIndexCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read -df examples/sample.yaml b.c") + result := test.RunCmd(cmd, "read -df examples/sample.yaml b.c") if result.Error == nil { t.Error("Expected command to fail due to invalid path") } expectedOutput := `Document index f is not a integer or *: strconv.ParseInt: parsing "f": invalid syntax` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestReadBadDocumentIndexCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read -d1 examples/sample.yaml b.c") + result := test.RunCmd(cmd, "read -d1 examples/sample.yaml b.c") if result.Error == nil { t.Error("Expected command to fail due to invalid path") } expectedOutput := `asked to process document index 1 but there are only 1 document(s)` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestReadOrderCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read examples/order.yaml") + result := test.RunCmd(cmd, "read examples/order.yaml") if result.Error != nil { t.Error(result.Error) } - assertResult(t, + test.AssertResult(t, `version: 3 application: MyApp `, @@ -152,20 +153,20 @@ application: MyApp func TestReadMultiCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read -d 1 examples/multiple_docs.yaml another.document") + result := test.RunCmd(cmd, "read -d 1 examples/multiple_docs.yaml another.document") if result.Error != nil { t.Error(result.Error) } - assertResult(t, "here\n", result.Output) + test.AssertResult(t, "here\n", result.Output) } func TestReadMultiAllCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read -d* examples/multiple_docs.yaml commonKey") + result := test.RunCmd(cmd, "read -d* examples/multiple_docs.yaml commonKey") if result.Error != nil { t.Error(result.Error) } - assertResult(t, + test.AssertResult(t, `- first document - second document - third document @@ -174,16 +175,16 @@ func TestReadMultiAllCmd(t *testing.T) { func TestReadCmd_ArrayYaml(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read examples/array.yaml [0].gather_facts") + result := test.RunCmd(cmd, "read examples/array.yaml [0].gather_facts") if result.Error != nil { t.Error(result.Error) } - assertResult(t, "false\n", result.Output) + test.AssertResult(t, "false\n", result.Output) } func TestReadCmd_ArrayYaml_NoPath(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read examples/array.yaml") + result := test.RunCmd(cmd, "read examples/array.yaml") if result.Error != nil { t.Error(result.Error) } @@ -196,12 +197,12 @@ func TestReadCmd_ArrayYaml_NoPath(t *testing.T) { - land serial: 1 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestReadCmd_ArrayYaml_OneElement(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read examples/array.yaml [0]") + result := test.RunCmd(cmd, "read examples/array.yaml [0]") if result.Error != nil { t.Error(result.Error) } @@ -214,12 +215,12 @@ roles: - land serial: 1 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestReadCmd_ArrayYaml_Splat(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read examples/array.yaml [*]") + result := test.RunCmd(cmd, "read examples/array.yaml [*]") if result.Error != nil { t.Error(result.Error) } @@ -232,62 +233,62 @@ func TestReadCmd_ArrayYaml_Splat(t *testing.T) { - land serial: 1 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestReadCmd_ArrayYaml_SplatKey(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read examples/array.yaml [*].gather_facts") + result := test.RunCmd(cmd, "read examples/array.yaml [*].gather_facts") if result.Error != nil { t.Error(result.Error) } expectedOutput := "- false\n" - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestReadCmd_ArrayYaml_ErrorBadPath(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read examples/array.yaml [x].gather_facts") + result := test.RunCmd(cmd, "read examples/array.yaml [x].gather_facts") if result.Error == nil { t.Error("Expected command to fail due to invalid path") } expectedOutput := `Error reading path in document index 0: error accessing array: strconv.ParseInt: parsing "x": invalid syntax` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestReadCmd_ArrayYaml_Splat_ErrorBadPath(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read examples/array.yaml [*].roles[x]") + result := test.RunCmd(cmd, "read examples/array.yaml [*].roles[x]") if result.Error == nil { t.Error("Expected command to fail due to invalid path") } expectedOutput := `Error reading path in document index 0: error accessing array: strconv.ParseInt: parsing "x": invalid syntax` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestReadCmd_Error(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read") + result := test.RunCmd(cmd, "read") if result.Error == nil { t.Error("Expected command to fail due to missing arg") } expectedOutput := `Must provide filename` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestReadCmd_ErrorEmptyFilename(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read ") + result := test.RunCmd(cmd, "read ") if result.Error == nil { t.Error("Expected command to fail due to missing arg") } expectedOutput := `Must provide filename` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestReadCmd_ErrorUnreadableFile(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read fake-unknown") + result := test.RunCmd(cmd, "read fake-unknown") if result.Error == nil { t.Error("Expected command to fail due to unknown file") } @@ -297,7 +298,7 @@ func TestReadCmd_ErrorUnreadableFile(t *testing.T) { } else { expectedOutput = `open fake-unknown: no such file or directory` } - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestReadCmd_ErrorBadPath(t *testing.T) { @@ -310,63 +311,63 @@ func TestReadCmd_ErrorBadPath(t *testing.T) { - 1 - 2 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("read %s b.d.*.[x]", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("read %s b.d.*.[x]", filename)) if result.Error == nil { t.Fatal("Expected command to fail due to invalid path") } expectedOutput := `Error reading path in document index 0: error accessing array: strconv.ParseInt: parsing "x": invalid syntax` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestReadCmd_Verbose(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "-v read examples/sample.yaml b.c") + result := test.RunCmd(cmd, "-v read examples/sample.yaml b.c") if result.Error != nil { t.Error(result.Error) } - assertResult(t, "2\n", result.Output) + test.AssertResult(t, "2\n", result.Output) } func TestReadCmd_NoTrim(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "--trim=false read examples/sample.yaml b.c") + result := test.RunCmd(cmd, "--trim=false read examples/sample.yaml b.c") if result.Error != nil { t.Error(result.Error) } - assertResult(t, "2\n\n", result.Output) + test.AssertResult(t, "2\n\n", result.Output) } func TestReadCmd_ToJson(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read -j examples/sample.yaml b.c") + result := test.RunCmd(cmd, "read -j examples/sample.yaml b.c") if result.Error != nil { t.Error(result.Error) } - assertResult(t, "2\n", result.Output) + test.AssertResult(t, "2\n", result.Output) } func TestReadCmd_ToJsonLong(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "read --tojson examples/sample.yaml b.c") + result := test.RunCmd(cmd, "read --tojson examples/sample.yaml b.c") if result.Error != nil { t.Error(result.Error) } - assertResult(t, "2\n", result.Output) + test.AssertResult(t, "2\n", result.Output) } func TestPrefixCmd(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("prefix %s d", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("prefix %s d", filename)) if result.Error != nil { t.Error(result.Error) } @@ -374,18 +375,18 @@ func TestPrefixCmd(t *testing.T) { b: c: 3 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestPrefixCmdArray(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("prefix %s [+].d.[+]", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("prefix %s [+].d.[+]", filename)) if result.Error != nil { t.Error(result.Error) } @@ -393,18 +394,18 @@ func TestPrefixCmdArray(t *testing.T) { - b: c: 3 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestPrefixCmd_MultiLayer(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("prefix %s d.e.f", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("prefix %s d.e.f", filename)) if result.Error != nil { t.Error(result.Error) } @@ -414,7 +415,7 @@ func TestPrefixCmd_MultiLayer(t *testing.T) { b: c: 3 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestPrefixMultiCmd(t *testing.T) { @@ -423,11 +424,11 @@ func TestPrefixMultiCmd(t *testing.T) { --- apples: great ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("prefix %s -d 1 d", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d 1 d", filename)) if result.Error != nil { t.Error(result.Error) } @@ -437,38 +438,38 @@ apples: great d: apples: great ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestPrefixInvalidDocumentIndexCmd(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("prefix %s -df d", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -df d", filename)) if result.Error == nil { t.Error("Expected command to fail due to invalid path") } expectedOutput := `Document index f is not a integer or *: strconv.ParseInt: parsing "f": invalid syntax` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestPrefixBadDocumentIndexCmd(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("prefix %s -d 1 d", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d 1 d", filename)) if result.Error == nil { t.Error("Expected command to fail due to invalid path") } expectedOutput := `asked to process document index 1 but there are only 1 document(s)` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestPrefixMultiAllCmd(t *testing.T) { content := `b: @@ -476,11 +477,11 @@ func TestPrefixMultiAllCmd(t *testing.T) { --- apples: great ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("prefix %s -d * d", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("prefix %s -d * d", filename)) if result.Error != nil { t.Error(result.Error) } @@ -490,22 +491,22 @@ apples: great --- d: apples: great` - assertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) + test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) } func TestPrefixCmd_Error(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "prefix") + result := test.RunCmd(cmd, "prefix") if result.Error == nil { t.Error("Expected command to fail due to missing arg") } expectedOutput := `Must provide ` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestPrefixCmd_ErrorUnreadableFile(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "prefix fake-unknown a.b") + result := test.RunCmd(cmd, "prefix fake-unknown a.b") if result.Error == nil { t.Error("Expected command to fail due to unknown file") } @@ -515,18 +516,18 @@ func TestPrefixCmd_ErrorUnreadableFile(t *testing.T) { } else { expectedOutput = `open fake-unknown: no such file or directory` } - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestPrefixCmd_Verbose(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("-v prefix %s x", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("-v prefix %s x", filename)) if result.Error != nil { t.Error(result.Error) } @@ -534,78 +535,78 @@ func TestPrefixCmd_Verbose(t *testing.T) { b: c: 3 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestPrefixCmd_Inplace(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("prefix -i %s d", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("prefix -i %s d", filename)) if result.Error != nil { t.Error(result.Error) } - gotOutput := readTempYamlFile(filename) + gotOutput := test.ReadTempYamlFile(filename) expectedOutput := `d: b: c: 3` - assertResult(t, expectedOutput, strings.Trim(gotOutput, "\n ")) + test.AssertResult(t, expectedOutput, strings.Trim(gotOutput, "\n ")) } func TestNewCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "new b.c 3") + result := test.RunCmd(cmd, "new b.c 3") if result.Error != nil { t.Error(result.Error) } expectedOutput := `b: c: 3 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestNewCmd_Error(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "new b.c") + result := test.RunCmd(cmd, "new b.c") if result.Error == nil { t.Error("Expected command to fail due to missing arg") } expectedOutput := `Must provide ` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestNewCmd_Verbose(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "-v new b.c 3") + result := test.RunCmd(cmd, "-v new b.c 3") if result.Error != nil { t.Error(result.Error) } expectedOutput := `b: c: 3 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestWriteCmd(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write %s b.c 7", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write %s b.c 7", filename)) if result.Error != nil { t.Error(result.Error) } expectedOutput := `b: c: 7 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestWriteMultiCmd(t *testing.T) { @@ -614,11 +615,11 @@ func TestWriteMultiCmd(t *testing.T) { --- apples: great ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write %s -d 1 apples ok", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write %s -d 1 apples ok", filename)) if result.Error != nil { t.Error(result.Error) } @@ -627,38 +628,38 @@ apples: great --- apples: ok ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestWriteInvalidDocumentIndexCmd(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write %s -df apples ok", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write %s -df apples ok", filename)) if result.Error == nil { t.Error("Expected command to fail due to invalid path") } expectedOutput := `Document index f is not a integer or *: strconv.ParseInt: parsing "f": invalid syntax` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestWriteBadDocumentIndexCmd(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write %s -d 1 apples ok", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write %s -d 1 apples ok", filename)) if result.Error == nil { t.Error("Expected command to fail due to invalid path") } expectedOutput := `asked to process document index 1 but there are only 1 document(s)` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestWriteMultiAllCmd(t *testing.T) { content := `b: @@ -666,11 +667,11 @@ func TestWriteMultiAllCmd(t *testing.T) { --- apples: great ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write %s -d * apples ok", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write %s -d * apples ok", filename)) if result.Error != nil { t.Error(result.Error) } @@ -679,38 +680,38 @@ apples: great apples: ok --- apples: ok` - assertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) + test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) } func TestWriteCmd_EmptyArray(t *testing.T) { content := `b: 3` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write %s a []", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write %s a []", filename)) if result.Error != nil { t.Error(result.Error) } expectedOutput := `b: 3 a: [] ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestWriteCmd_Error(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "write") + result := test.RunCmd(cmd, "write") if result.Error == nil { t.Error("Expected command to fail due to missing arg") } expectedOutput := `Must provide ` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestWriteCmd_ErrorUnreadableFile(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "write fake-unknown a.b 3") + result := test.RunCmd(cmd, "write fake-unknown a.b 3") if result.Error == nil { t.Error("Expected command to fail due to unknown file") } @@ -720,54 +721,54 @@ func TestWriteCmd_ErrorUnreadableFile(t *testing.T) { } else { expectedOutput = `open fake-unknown: no such file or directory` } - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestWriteCmd_Verbose(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("-v write %s b.c 7", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("-v write %s b.c 7", filename)) if result.Error != nil { t.Error(result.Error) } expectedOutput := `b: c: 7 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestWriteCmd_Inplace(t *testing.T) { content := `b: c: 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write -i %s b.c 7", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write -i %s b.c 7", filename)) if result.Error != nil { t.Error(result.Error) } - gotOutput := readTempYamlFile(filename) + gotOutput := test.ReadTempYamlFile(filename) expectedOutput := `b: c: 7` - assertResult(t, expectedOutput, strings.Trim(gotOutput, "\n ")) + test.AssertResult(t, expectedOutput, strings.Trim(gotOutput, "\n ")) } func TestWriteCmd_Append(t *testing.T) { content := `b: - foo ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write %s b[+] 7", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write %s b[+] 7", filename)) if result.Error != nil { t.Error(result.Error) } @@ -775,17 +776,17 @@ func TestWriteCmd_Append(t *testing.T) { - foo - 7 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestWriteCmd_AppendEmptyArray(t *testing.T) { content := `a: 2 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write -v %s b[+] v", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write -v %s b[+] v", filename)) if result.Error != nil { t.Error(result.Error) } @@ -793,7 +794,7 @@ func TestWriteCmd_AppendEmptyArray(t *testing.T) { b: - v ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestWriteCmd_SplatArray(t *testing.T) { @@ -801,11 +802,11 @@ func TestWriteCmd_SplatArray(t *testing.T) { - c: thing - c: another thing ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write -v %s b[*].c new", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write -v %s b[*].c new", filename)) if result.Error != nil { t.Error(result.Error) } @@ -813,7 +814,7 @@ func TestWriteCmd_SplatArray(t *testing.T) { - c: new - c: new ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestWriteCmd_SplatMap(t *testing.T) { @@ -821,11 +822,11 @@ func TestWriteCmd_SplatMap(t *testing.T) { c: thing d: another thing ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write -v %s b.* new", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write -v %s b.* new", filename)) if result.Error != nil { t.Error(result.Error) } @@ -833,7 +834,7 @@ func TestWriteCmd_SplatMap(t *testing.T) { c: new d: new ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestWriteCmd_SplatMapEmpty(t *testing.T) { @@ -841,11 +842,11 @@ func TestWriteCmd_SplatMapEmpty(t *testing.T) { c: thing d: another thing ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("write -v %s b.c.* new", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("write -v %s b.c.* new", filename)) if result.Error != nil { t.Error(result.Error) } @@ -853,7 +854,7 @@ func TestWriteCmd_SplatMapEmpty(t *testing.T) { c: thing d: another thing ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestDeleteYaml(t *testing.T) { @@ -862,11 +863,11 @@ b: c: things d: something else ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("delete %s b.c", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("delete %s b.c", filename)) if result.Error != nil { t.Error(result.Error) } @@ -875,7 +876,7 @@ b: b: d: something else ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestDeleteSplatYaml(t *testing.T) { @@ -891,11 +892,11 @@ b: c: more things d: more something else ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("delete -v %s b.*.c", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("delete -v %s b.*.c", filename)) if result.Error != nil { t.Error(result.Error) } @@ -909,7 +910,7 @@ b: there: d: more something else ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestDeleteSplatArrayYaml(t *testing.T) { @@ -921,11 +922,11 @@ b: - thing: item2 name: sam ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("delete -v %s b.hi[*].thing", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("delete -v %s b.hi[*].thing", filename)) if result.Error != nil { t.Error(result.Error) } @@ -936,7 +937,7 @@ b: - name: fred - name: sam ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestDeleteSplatPrefixYaml(t *testing.T) { @@ -952,11 +953,11 @@ b: c: more things also d: more something else also ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("delete -v %s b.there*.c", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("delete -v %s b.there*.c", filename)) if result.Error != nil { t.Error(result.Error) } @@ -971,7 +972,7 @@ b: there2: d: more something else also ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestDeleteYamlArray(t *testing.T) { @@ -979,11 +980,11 @@ func TestDeleteYamlArray(t *testing.T) { - 2 - 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("delete %s [1]", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("delete %s [1]", filename)) if result.Error != nil { t.Error(result.Error) } @@ -991,7 +992,7 @@ func TestDeleteYamlArray(t *testing.T) { expectedOutput := `- 1 - 3 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestDeleteYamlMulti(t *testing.T) { @@ -1001,11 +1002,11 @@ func TestDeleteYamlMulti(t *testing.T) { - 2 - 3 ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("delete -d 1 %s [1]", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("delete -d 1 %s [1]", filename)) if result.Error != nil { t.Error(result.Error) } @@ -1015,7 +1016,7 @@ func TestDeleteYamlMulti(t *testing.T) { - 1 - 3 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestDeleteYamlMultiAllCmd(t *testing.T) { @@ -1026,11 +1027,11 @@ apples: great apples: great something: else ` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("delete %s -d * apples", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("delete %s -d * apples", filename)) if result.Error != nil { t.Error(result.Error) } @@ -1038,12 +1039,12 @@ something: else c: 3 --- something: else` - assertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) + test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) } func TestMergeCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "merge examples/data1.yaml examples/data2.yaml") + result := test.RunCmd(cmd, "merge examples/data1.yaml examples/data2.yaml") if result.Error != nil { t.Error(result.Error) } @@ -1054,12 +1055,12 @@ b: c: test: 1 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestMergeOverwriteCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "merge --overwrite examples/data1.yaml examples/data2.yaml") + result := test.RunCmd(cmd, "merge --overwrite examples/data1.yaml examples/data2.yaml") if result.Error != nil { t.Error(result.Error) } @@ -1070,12 +1071,12 @@ b: c: test: 1 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestMergeAppendCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "merge --append examples/data1.yaml examples/data2.yaml") + result := test.RunCmd(cmd, "merge --append examples/data1.yaml examples/data2.yaml") if result.Error != nil { t.Error(result.Error) } @@ -1088,11 +1089,11 @@ b: c: test: 1 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestMergeArraysCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "merge --append examples/sample_array.yaml examples/sample_array_2.yaml") + result := test.RunCmd(cmd, "merge --append examples/sample_array.yaml examples/sample_array_2.yaml") if result.Error != nil { t.Error(result.Error) } @@ -1102,12 +1103,12 @@ func TestMergeArraysCmd(t *testing.T) { - 4 - 5 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestMergeCmd_Multi(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "merge -d1 examples/multiple_docs_small.yaml examples/data2.yaml") + result := test.RunCmd(cmd, "merge -d1 examples/multiple_docs_small.yaml examples/data2.yaml") if result.Error != nil { t.Error(result.Error) } @@ -1124,7 +1125,7 @@ c: --- - 1 - 2` - assertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) + test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) } func TestMergeYamlMultiAllCmd(t *testing.T) { @@ -1133,16 +1134,16 @@ func TestMergeYamlMultiAllCmd(t *testing.T) { apples: green --- something: else` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) mergeContent := `apples: red something: good` - mergeFilename := writeTempYamlFile(mergeContent) - defer removeTempYamlFile(mergeFilename) + mergeFilename := test.WriteTempYamlFile(mergeContent) + defer test.RemoveTempYamlFile(mergeFilename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("merge -d* %s %s", filename, mergeFilename)) + result := test.RunCmd(cmd, fmt.Sprintf("merge -d* %s %s", filename, mergeFilename)) if result.Error != nil { t.Error(result.Error) } @@ -1153,7 +1154,7 @@ something: good --- apples: red something: else` - assertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) + test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) } func TestMergeYamlMultiAllOverwriteCmd(t *testing.T) { @@ -1162,16 +1163,16 @@ func TestMergeYamlMultiAllOverwriteCmd(t *testing.T) { apples: green --- something: else` - filename := writeTempYamlFile(content) - defer removeTempYamlFile(filename) + filename := test.WriteTempYamlFile(content) + defer test.RemoveTempYamlFile(filename) mergeContent := `apples: red something: good` - mergeFilename := writeTempYamlFile(mergeContent) - defer removeTempYamlFile(mergeFilename) + mergeFilename := test.WriteTempYamlFile(mergeContent) + defer test.RemoveTempYamlFile(mergeFilename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("merge --overwrite -d* %s %s", filename, mergeFilename)) + result := test.RunCmd(cmd, fmt.Sprintf("merge --overwrite -d* %s %s", filename, mergeFilename)) if result.Error != nil { t.Error(result.Error) } @@ -1182,22 +1183,22 @@ something: good --- apples: red something: good` - assertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) + test.AssertResult(t, expectedOutput, strings.Trim(result.Output, "\n ")) } func TestMergeCmd_Error(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "merge examples/data1.yaml") + result := test.RunCmd(cmd, "merge examples/data1.yaml") if result.Error == nil { t.Error("Expected command to fail due to missing arg") } expectedOutput := `Must provide at least 2 yaml files` - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestMergeCmd_ErrorUnreadableFile(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "merge examples/data1.yaml fake-unknown") + result := test.RunCmd(cmd, "merge examples/data1.yaml fake-unknown") if result.Error == nil { t.Error("Expected command to fail due to unknown file") } @@ -1207,12 +1208,12 @@ func TestMergeCmd_ErrorUnreadableFile(t *testing.T) { } else { expectedOutput = `Error updating document at index 0: open fake-unknown: no such file or directory` } - assertResult(t, expectedOutput, result.Error.Error()) + test.AssertResult(t, expectedOutput, result.Error.Error()) } func TestMergeCmd_Verbose(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "-v merge examples/data1.yaml examples/data2.yaml") + result := test.RunCmd(cmd, "-v merge examples/data1.yaml examples/data2.yaml") if result.Error != nil { t.Error(result.Error) } @@ -1223,37 +1224,37 @@ b: c: test: 1 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } func TestMergeCmd_Inplace(t *testing.T) { - filename := writeTempYamlFile(readTempYamlFile("examples/data1.yaml")) + filename := test.WriteTempYamlFile(test.ReadTempYamlFile("examples/data1.yaml")) err := os.Chmod(filename, os.FileMode(int(0666))) if err != nil { t.Error(err) } - defer removeTempYamlFile(filename) + defer test.RemoveTempYamlFile(filename) cmd := getRootCommand() - result := runCmd(cmd, fmt.Sprintf("merge -i %s examples/data2.yaml", filename)) + result := test.RunCmd(cmd, fmt.Sprintf("merge -i %s examples/data2.yaml", filename)) if result.Error != nil { t.Error(result.Error) } info, _ := os.Stat(filename) - gotOutput := readTempYamlFile(filename) + gotOutput := test.ReadTempYamlFile(filename) expectedOutput := `a: simple b: - 1 - 2 c: test: 1` - assertResult(t, expectedOutput, strings.Trim(gotOutput, "\n ")) - assertResult(t, os.FileMode(int(0666)), info.Mode()) + test.AssertResult(t, expectedOutput, strings.Trim(gotOutput, "\n ")) + test.AssertResult(t, os.FileMode(int(0666)), info.Mode()) } func TestMergeAllowEmptyCmd(t *testing.T) { cmd := getRootCommand() - result := runCmd(cmd, "merge --allow-empty examples/data1.yaml examples/empty.yaml") + result := test.RunCmd(cmd, "merge --allow-empty examples/data1.yaml examples/empty.yaml") if result.Error != nil { t.Error(result.Error) } @@ -1262,5 +1263,5 @@ b: - 1 - 2 ` - assertResult(t, expectedOutput, result.Output) + test.AssertResult(t, expectedOutput, result.Output) } diff --git a/json_converter_test.go b/json_converter_test.go deleted file mode 100644 index 026c522d..00000000 --- a/json_converter_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package main - -import ( - "testing" -) - -func TestJsonToString(t *testing.T) { - var data = parseData(` ---- -b: - c: 2 -`) - got, _ := jsonToString(data) - assertResult(t, "{\"b\":{\"c\":2}}", got) -} - -func TestJsonToString_withIntKey(t *testing.T) { - var data = parseData(` ---- -b: - 2: c -`) - got, _ := jsonToString(data) - assertResult(t, `{"b":{"2":"c"}}`, got) -} - -func TestJsonToString_withBoolKey(t *testing.T) { - var data = parseData(` ---- -b: - false: c -`) - got, _ := jsonToString(data) - assertResult(t, `{"b":{"false":"c"}}`, got) -} - -func TestJsonToString_withArray(t *testing.T) { - var data = parseData(` ---- -b: - - item: one - - item: two -`) - got, _ := jsonToString(data) - assertResult(t, "{\"b\":[{\"item\":\"one\"},{\"item\":\"two\"}]}", got) -} diff --git a/merge.go b/merge.go deleted file mode 100644 index e80bce36..00000000 --- a/merge.go +++ /dev/null @@ -1,12 +0,0 @@ -package main - -import mergo "gopkg.in/imdario/mergo.v0" - -func merge(dst interface{}, src interface{}, overwrite bool, append bool) error { - if overwrite { - return mergo.Merge(dst, src, mergo.WithOverride) - } else if append { - return mergo.Merge(dst, src, mergo.WithAppendSlice) - } - return mergo.Merge(dst, src) -} diff --git a/data_navigator.go b/pkg/yqlib/data_navigator.go similarity index 91% rename from data_navigator.go rename to pkg/yqlib/data_navigator.go index 5746db70..2b66dee5 100644 --- a/data_navigator.go +++ b/pkg/yqlib/data_navigator.go @@ -1,4 +1,4 @@ -package main +package yqlib import ( "fmt" @@ -77,17 +77,17 @@ func writeMap(context interface{}, paths []string, value interface{}) interface{ remainingPaths := paths[1:] for _, child := range children { - child.Value = updatedChildValue(child.Value, remainingPaths, value) + child.Value = UpdatedChildValue(child.Value, remainingPaths, value) } log.Debugf("\tReturning mapSlice %v\n", mapSlice) return mapSlice } -func updatedChildValue(child interface{}, remainingPaths []string, value interface{}) interface{} { +func UpdatedChildValue(child interface{}, remainingPaths []string, value interface{}) interface{} { if len(remainingPaths) == 0 { return value } - log.Debugf("updatedChildValue for child %v with path %v to set value %v", child, remainingPaths, value) + log.Debugf("UpdatedChildValue for child %v with path %v to set value %v", child, remainingPaths, value) log.Debugf("type of child is %v", reflect.TypeOf(child)) switch child := child.(type) { @@ -123,12 +123,12 @@ func writeArray(context interface{}, paths []string, value interface{}) []interf index = int64(len(array)) } else if rawIndex == "*" { for index, oldChild := range array { - array[index] = updatedChildValue(oldChild, remainingPaths, value) + array[index] = UpdatedChildValue(oldChild, remainingPaths, value) } return array } else { index, _ = strconv.ParseInt(rawIndex, 10, 64) // nolint - // writeArray is only called by updatedChildValue which handles parsing the + // writeArray is only called by UpdatedChildValue which handles parsing the // index, as such this renders this dead code. } @@ -139,7 +139,7 @@ func writeArray(context interface{}, paths []string, value interface{}) []interf log.Debugf("\tcurrentChild %v\n", currentChild) - array[index] = updatedChildValue(currentChild, remainingPaths, value) + array[index] = UpdatedChildValue(currentChild, remainingPaths, value) log.Debugf("\tReturning array %v\n", array) return array } @@ -174,7 +174,7 @@ func readMapSplat(context yaml.MapSlice, tail []string) (interface{}, error) { var i = 0 for _, entry := range context { if len(tail) > 0 { - val, err := recurse(entry.Value, tail[0], tail[1:]) + val, err := Recurse(entry.Value, tail[0], tail[1:]) if err != nil { return nil, err } @@ -187,7 +187,7 @@ func readMapSplat(context yaml.MapSlice, tail []string) (interface{}, error) { return newArray, nil } -func recurse(value interface{}, head string, tail []string) (interface{}, error) { +func Recurse(value interface{}, head string, tail []string) (interface{}, error) { switch value := value.(type) { case []interface{}: if head == "*" { @@ -228,7 +228,7 @@ func readArraySplat(array []interface{}, tail []string) (interface{}, error) { func calculateValue(value interface{}, tail []string) (interface{}, error) { if len(tail) > 0 { - return recurse(value, tail[0], tail[1:]) + return Recurse(value, tail[0], tail[1:]) } return value, nil } @@ -266,7 +266,7 @@ func deleteEntryInMap(original yaml.MapSlice, child yaml.MapItem, index int, pat if len(remainingPaths) > 0 { newChild := yaml.MapItem{Key: child.Key} var errorDeleting error - newChild.Value, errorDeleting = deleteChildValue(child.Value, remainingPaths) + newChild.Value, errorDeleting = DeleteChildValue(child.Value, remainingPaths) if errorDeleting != nil { return nil, errorDeleting } @@ -293,7 +293,7 @@ func deleteArraySplat(array []interface{}, tail []string) (interface{}, error) { log.Debugf("deleteArraySplat for %v for %v\n", tail, array) var newArray = make([]interface{}, len(array)) for index, value := range array { - val, err := deleteChildValue(value, tail) + val, err := DeleteChildValue(value, tail) if err != nil { return nil, err } @@ -328,8 +328,8 @@ func deleteArray(array []interface{}, paths []string, index int64) (interface{}, return array, nil } -func deleteChildValue(child interface{}, remainingPaths []string) (interface{}, error) { - log.Debugf("deleteChildValue for %v for %v\n", remainingPaths, child) +func DeleteChildValue(child interface{}, remainingPaths []string) (interface{}, error) { + log.Debugf("DeleteChildValue for %v for %v\n", remainingPaths, child) var head = remainingPaths[0] var tail = remainingPaths[1:] switch child := child.(type) { diff --git a/data_navigator_test.go b/pkg/yqlib/data_navigator_test.go similarity index 62% rename from data_navigator_test.go rename to pkg/yqlib/data_navigator_test.go index 206346ff..ff772e13 100644 --- a/data_navigator_test.go +++ b/pkg/yqlib/data_navigator_test.go @@ -1,32 +1,33 @@ -package main +package yqlib import ( "fmt" "sort" "testing" + "github.com/mikefarah/yq/test" ) func TestReadMap_simple(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- b: c: 2 `) got, _ := readMap(data, "b", []string{"c"}) - assertResult(t, 2, got) + test.AssertResult(t, 2, got) } func TestReadMap_numberKey(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- 200: things `) got, _ := readMap(data, "200", []string{}) - assertResult(t, "things", got) + test.AssertResult(t, "things", got) } func TestReadMap_splat(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- mapSplat: item1: things @@ -34,11 +35,11 @@ mapSplat: otherThing: cat `) res, _ := readMap(data, "mapSplat", []string{"*"}) - assertResult(t, "[things whatever cat]", fmt.Sprintf("%v", res)) + test.AssertResult(t, "[things whatever cat]", fmt.Sprintf("%v", res)) } func TestReadMap_prefixSplat(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- mapSplat: item1: things @@ -46,11 +47,11 @@ mapSplat: otherThing: cat `) res, _ := readMap(data, "mapSplat", []string{"item*"}) - assertResult(t, "[things whatever]", fmt.Sprintf("%v", res)) + test.AssertResult(t, "[things whatever]", fmt.Sprintf("%v", res)) } func TestReadMap_deep_splat(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- mapSplatDeep: item1: @@ -63,30 +64,30 @@ mapSplatDeep: result := res.([]interface{}) var actual = []string{result[0].(string), result[1].(string)} sort.Strings(actual) - assertResult(t, "[apples bananas]", fmt.Sprintf("%v", actual)) + test.AssertResult(t, "[apples bananas]", fmt.Sprintf("%v", actual)) } func TestReadMap_key_doesnt_exist(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- b: c: 2 `) got, _ := readMap(data, "b.x.f", []string{"c"}) - assertResult(t, nil, got) + test.AssertResult(t, nil, got) } func TestReadMap_recurse_against_string(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- a: cat `) got, _ := readMap(data, "a", []string{"b"}) - assertResult(t, nil, got) + test.AssertResult(t, nil, got) } func TestReadMap_with_array(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- b: d: @@ -94,11 +95,11 @@ b: - 4 `) got, _ := readMap(data, "b", []string{"d", "1"}) - assertResult(t, 4, got) + test.AssertResult(t, 4, got) } func TestReadMap_with_array_and_bad_index(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- b: d: @@ -110,11 +111,11 @@ b: t.Fatal("Expected error due to invalid path") } expectedOutput := `error accessing array: strconv.ParseInt: parsing "x": invalid syntax` - assertResult(t, expectedOutput, err.Error()) + test.AssertResult(t, expectedOutput, err.Error()) } func TestReadMap_with_mapsplat_array_and_bad_index(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- b: d: @@ -130,11 +131,11 @@ b: t.Fatal("Expected error due to invalid path") } expectedOutput := `error accessing array: strconv.ParseInt: parsing "x": invalid syntax` - assertResult(t, expectedOutput, err.Error()) + test.AssertResult(t, expectedOutput, err.Error()) } func TestReadMap_with_arraysplat_map_array_and_bad_index(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- b: d: @@ -150,11 +151,11 @@ b: t.Fatal("Expected error due to invalid path") } expectedOutput := `error accessing array: strconv.ParseInt: parsing "x": invalid syntax` - assertResult(t, expectedOutput, err.Error()) + test.AssertResult(t, expectedOutput, err.Error()) } func TestReadMap_with_array_out_of_bounds(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- b: d: @@ -162,11 +163,11 @@ b: - 4 `) got, _ := readMap(data, "b", []string{"d", "3"}) - assertResult(t, nil, got) + test.AssertResult(t, nil, got) } func TestReadMap_with_array_out_of_bounds_by_1(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` --- b: d: @@ -174,11 +175,11 @@ b: - 4 `) got, _ := readMap(data, "b", []string{"d", "2"}) - assertResult(t, nil, got) + test.AssertResult(t, nil, got) } func TestReadMap_with_array_splat(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` e: - name: Fred @@ -188,71 +189,71 @@ e: thing: dog `) got, _ := readMap(data, "e", []string{"*", "name"}) - assertResult(t, "[Fred Sam]", fmt.Sprintf("%v", got)) + test.AssertResult(t, "[Fred Sam]", fmt.Sprintf("%v", got)) } func TestWrite_really_simple(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` b: 2 `) updated := writeMap(data, []string{"b"}, "4") - assertResult(t, "[{b 4}]", fmt.Sprintf("%v", updated)) + test.AssertResult(t, "[{b 4}]", fmt.Sprintf("%v", updated)) } func TestWrite_simple(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` b: c: 2 `) updated := writeMap(data, []string{"b", "c"}, "4") - assertResult(t, "[{b [{c 4}]}]", fmt.Sprintf("%v", updated)) + test.AssertResult(t, "[{b [{c 4}]}]", fmt.Sprintf("%v", updated)) } func TestWrite_new(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` b: c: 2 `) updated := writeMap(data, []string{"b", "d"}, "4") - assertResult(t, "[{b [{c 2} {d 4}]}]", fmt.Sprintf("%v", updated)) + test.AssertResult(t, "[{b [{c 2} {d 4}]}]", fmt.Sprintf("%v", updated)) } func TestWrite_new_deep(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` b: c: 2 `) updated := writeMap(data, []string{"b", "d", "f"}, "4") - assertResult(t, "[{b [{c 2} {d [{f 4}]}]}]", fmt.Sprintf("%v", updated)) + test.AssertResult(t, "[{b [{c 2} {d [{f 4}]}]}]", fmt.Sprintf("%v", updated)) } func TestWrite_array(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` b: - aa `) updated := writeMap(data, []string{"b", "0"}, "bb") - assertResult(t, "[{b [bb]}]", fmt.Sprintf("%v", updated)) + test.AssertResult(t, "[{b [bb]}]", fmt.Sprintf("%v", updated)) } func TestWrite_new_array(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` b: c: 2 `) updated := writeMap(data, []string{"b", "0"}, "4") - assertResult(t, "[{b [{c 2} {0 4}]}]", fmt.Sprintf("%v", updated)) + test.AssertResult(t, "[{b [{c 2} {0 4}]}]", fmt.Sprintf("%v", updated)) } func TestWrite_new_array_deep(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` a: apple `) @@ -261,12 +262,12 @@ b: - c: "4"` updated := writeMap(data, []string{"b", "+", "c"}, "4") - got, _ := yamlToString(updated) - assertResult(t, expected, got) + got, _ := YamlToString(updated, true) + test.AssertResult(t, expected, got) } func TestWrite_new_map_array_deep(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` b: c: 2 `) @@ -276,12 +277,12 @@ b: - "4"` updated := writeMap(data, []string{"b", "d", "+"}, "4") - got, _ := yamlToString(updated) - assertResult(t, expected, got) + got, _ := YamlToString(updated, true) + test.AssertResult(t, expected, got) } func TestWrite_add_to_array(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` b: - aa `) @@ -291,109 +292,109 @@ b: - bb` updated := writeMap(data, []string{"b", "1"}, "bb") - got, _ := yamlToString(updated) - assertResult(t, expected, got) + got, _ := YamlToString(updated, true) + test.AssertResult(t, expected, got) } func TestWrite_with_no_tail(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` b: c: 2 `) updated := writeMap(data, []string{"b"}, "4") - assertResult(t, "[{b 4}]", fmt.Sprintf("%v", updated)) + test.AssertResult(t, "[{b 4}]", fmt.Sprintf("%v", updated)) } func TestWriteMap_no_paths(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` b: 5 `) result := writeMap(data, []string{}, 4) - assertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) + test.AssertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) } func TestWriteArray_no_paths(t *testing.T) { var data = make([]interface{}, 1) data[0] = "mike" result := writeArray(data, []string{}, 4) - assertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) + test.AssertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) } func TestDelete_MapItem(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` a: 123 b: 456 `) - var expected = parseData(` + var expected = test.ParseData(` b: 456 `) result, _ := deleteMap(data, []string{"a"}) - assertResult(t, fmt.Sprintf("%v", expected), fmt.Sprintf("%v", result)) + test.AssertResult(t, fmt.Sprintf("%v", expected), fmt.Sprintf("%v", result)) } // Ensure deleting an index into a string does nothing func TestDelete_index_to_string(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` a: mystring `) result, _ := deleteMap(data, []string{"a", "0"}) - assertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) + test.AssertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) } func TestDelete_list_index(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` a: [3, 4] `) - var expected = parseData(` + var expected = test.ParseData(` a: [3] `) result, _ := deleteMap(data, []string{"a", "1"}) - assertResult(t, fmt.Sprintf("%v", expected), fmt.Sprintf("%v", result)) + test.AssertResult(t, fmt.Sprintf("%v", expected), fmt.Sprintf("%v", result)) } func TestDelete_list_index_beyond_bounds(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` a: [3, 4] `) result, _ := deleteMap(data, []string{"a", "5"}) - assertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) + test.AssertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) } func TestDelete_list_index_out_of_bounds_by_1(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` a: [3, 4] `) result, _ := deleteMap(data, []string{"a", "2"}) - assertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) + test.AssertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) } func TestDelete_no_paths(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` a: [3, 4] b: - name: test `) result, _ := deleteMap(data, []string{}) - assertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) + test.AssertResult(t, fmt.Sprintf("%v", data), fmt.Sprintf("%v", result)) } func TestDelete_array_map_item(t *testing.T) { - var data = parseData(` + var data = test.ParseData(` b: - name: fred value: blah - name: john value: test `) - var expected = parseData(` + var expected = test.ParseData(` b: - value: blah - name: john value: test `) result, _ := deleteMap(data, []string{"b", "0", "name"}) - assertResult(t, fmt.Sprintf("%v", expected), fmt.Sprintf("%v", result)) + test.AssertResult(t, fmt.Sprintf("%v", expected), fmt.Sprintf("%v", result)) } diff --git a/json_converter.go b/pkg/yqlib/json_converter.go similarity index 93% rename from json_converter.go rename to pkg/yqlib/json_converter.go index 10e152b9..e8371885 100644 --- a/json_converter.go +++ b/pkg/yqlib/json_converter.go @@ -1,4 +1,4 @@ -package main +package yqlib import ( "encoding/json" @@ -8,7 +8,7 @@ import ( yaml "github.com/mikefarah/yaml/v2" ) -func jsonToString(context interface{}) (string, error) { +func JsonToString(context interface{}) (string, error) { out, err := json.Marshal(toJSON(context)) if err != nil { return "", fmt.Errorf("error printing yaml as json: %v", err) diff --git a/pkg/yqlib/json_converter_test.go b/pkg/yqlib/json_converter_test.go new file mode 100644 index 00000000..ae1c08d8 --- /dev/null +++ b/pkg/yqlib/json_converter_test.go @@ -0,0 +1,47 @@ +package yqlib + +import ( + "testing" + "github.com/mikefarah/yq/test" +) + +func TestJsonToString(t *testing.T) { + var data = test.ParseData(` +--- +b: + c: 2 +`) + got, _ := JsonToString(data) + test.AssertResult(t, "{\"b\":{\"c\":2}}", got) +} + +func TestJsonToString_withIntKey(t *testing.T) { + var data = test.ParseData(` +--- +b: + 2: c +`) + got, _ := JsonToString(data) + test.AssertResult(t, `{"b":{"2":"c"}}`, got) +} + +func TestJsonToString_withBoolKey(t *testing.T) { + var data = test.ParseData(` +--- +b: + false: c +`) + got, _ := JsonToString(data) + test.AssertResult(t, `{"b":{"false":"c"}}`, got) +} + +func TestJsonToString_withArray(t *testing.T) { + var data = test.ParseData(` +--- +b: + - item: one + - item: two +`) + got, _ := JsonToString(data) + test.AssertResult(t, "{\"b\":[{\"item\":\"one\"},{\"item\":\"two\"}]}", got) +} diff --git a/pkg/yqlib/lib.go b/pkg/yqlib/lib.go new file mode 100644 index 00000000..fe3a986b --- /dev/null +++ b/pkg/yqlib/lib.go @@ -0,0 +1,54 @@ +package yqlib + +import ( + mergo "gopkg.in/imdario/mergo.v0" + logging "gopkg.in/op/go-logging.v1" +) + +var log = logging.MustGetLogger("yq") + +func SetLogger(l *logging.Logger) { + log = l +} + +func ReadPath(dataBucket interface{}, path string) (interface{}, error) { + var paths = ParsePath(path) + return Recurse(dataBucket, paths[0], paths[1:]) +} + +func WritePath(dataBucket interface{}, path string, value interface{}) (interface{}) { + var paths = ParsePath(path) + return UpdatedChildValue(dataBucket, paths, value) +} + +func PrefixPath(dataBucket interface{}, prefix string) (interface{}) { + var paths = ParsePath(prefix) + + // Inverse order + for i := len(paths)/2 - 1; i >= 0; i-- { + opp := len(paths) - 1 - i + paths[i], paths[opp] = paths[opp], paths[i] + } + + var mapDataBucket = dataBucket + for _, key := range paths { + singlePath := []string{key} + mapDataBucket = UpdatedChildValue(nil, singlePath, mapDataBucket) + } + + return mapDataBucket +} + +func DeletePath(dataBucket interface{}, path string) (interface{}, error) { + var paths = ParsePath(path) + return DeleteChildValue(dataBucket, paths) +} + +func Merge(dst interface{}, src interface{}, overwrite bool, append bool) error { + if overwrite { + return mergo.Merge(dst, src, mergo.WithOverride) + } else if append { + return mergo.Merge(dst, src, mergo.WithAppendSlice) + } + return mergo.Merge(dst, src) +} \ No newline at end of file diff --git a/pkg/yqlib/lib_test.go b/pkg/yqlib/lib_test.go new file mode 100644 index 00000000..f0511f19 --- /dev/null +++ b/pkg/yqlib/lib_test.go @@ -0,0 +1,148 @@ +package yqlib + +import ( + "fmt" + "testing" + "github.com/mikefarah/yq/test" +) + +func TestReadPath(t *testing.T) { + var data = test.ParseData(` +--- +b: + 2: c +`) + + got, _ := ReadPath(data, "b.2") + test.AssertResult(t, `c`, got) +} + +func TestReadPath_WithError(t *testing.T) { + var data = test.ParseData(` +--- +b: + - c +`) + + _, err := ReadPath(data, "b.[a]") + if err == nil { + t.Fatal("Expected error due to invalid path") + } +} + +func TestWritePath(t *testing.T) { + var data = test.ParseData(` +--- +b: + 2: c +`) + + got := WritePath(data, "b.3", "a") + test.AssertResult(t, `[{b [{2 c} {3 a}]}]`, fmt.Sprintf("%v", got)) +} + +func TestPrefixPath(t *testing.T) { + var data = test.ParseData(` +--- +b: + 2: c +`) + + got := PrefixPath(data, "d") + test.AssertResult(t, `[{d [{b [{2 c}]}]}]`, fmt.Sprintf("%v", got)) +} + +func TestDeletePath(t *testing.T) { + var data = test.ParseData(` +--- +b: + 2: c + 3: a +`) + + got, _ := DeletePath(data, "b.2") + test.AssertResult(t, `[{b [{3 a}]}]`, fmt.Sprintf("%v", got)) +} + +func TestDeletePath_WithError(t *testing.T) { + var data = test.ParseData(` +--- +b: + - c +`) + + _, err := DeletePath(data, "b.[a]") + if err == nil { + t.Fatal("Expected error due to invalid path") + } +} + +func TestMerge(t *testing.T) { + var dst = test.ParseData(` +--- +a: b +c: d +`) + var src = test.ParseData(` +--- +a: 1 +b: 2 +`) + + var mergedData = make(map[interface{}]interface{}) + mergedData["root"] = dst + var mapDataBucket = make(map[interface{}]interface{}) + mapDataBucket["root"] = src + + Merge(&mergedData, mapDataBucket, false, false) + test.AssertResult(t, `[{a b} {c d}]`, fmt.Sprintf("%v", mergedData["root"])) +} + +func TestMerge_WithOverwrite(t *testing.T) { + var dst = test.ParseData(` +--- +a: b +c: d +`) + var src = test.ParseData(` +--- +a: 1 +b: 2 +`) + + var mergedData = make(map[interface{}]interface{}) + mergedData["root"] = dst + var mapDataBucket = make(map[interface{}]interface{}) + mapDataBucket["root"] = src + + Merge(&mergedData, mapDataBucket, true, false) + test.AssertResult(t, `[{a 1} {b 2}]`, fmt.Sprintf("%v", mergedData["root"])) +} + +func TestMerge_WithAppend(t *testing.T) { + var dst = test.ParseData(` +--- +a: b +c: d +`) + var src = test.ParseData(` +--- +a: 1 +b: 2 +`) + + var mergedData = make(map[interface{}]interface{}) + mergedData["root"] = dst + var mapDataBucket = make(map[interface{}]interface{}) + mapDataBucket["root"] = src + + Merge(&mergedData, mapDataBucket, false, true) + test.AssertResult(t, `[{a b} {c d} {a 1} {b 2}]`, fmt.Sprintf("%v", mergedData["root"])) +} + +func TestMerge_WithError(t *testing.T) { + err := Merge(nil, nil, false, false) + if err == nil { + t.Fatal("Expected error due to nil") + } +} \ No newline at end of file diff --git a/path_parser.go b/pkg/yqlib/path_parser.go similarity index 96% rename from path_parser.go rename to pkg/yqlib/path_parser.go index 0eed4a49..a416b722 100644 --- a/path_parser.go +++ b/pkg/yqlib/path_parser.go @@ -1,6 +1,6 @@ -package main +package yqlib -func parsePath(path string) []string { +func ParsePath(path string) []string { return parsePathAccum([]string{}, path) } diff --git a/path_parser_test.go b/pkg/yqlib/path_parser_test.go similarity index 74% rename from path_parser_test.go rename to pkg/yqlib/path_parser_test.go index a8088d37..7680aa82 100644 --- a/path_parser_test.go +++ b/pkg/yqlib/path_parser_test.go @@ -1,7 +1,8 @@ -package main +package yqlib import ( "testing" + "github.com/mikefarah/yq/test" ) var parsePathsTests = []struct { @@ -15,7 +16,7 @@ var parsePathsTests = []struct { func TestParsePath(t *testing.T) { for _, tt := range parsePathsTests { - assertResultComplex(t, tt.expectedPaths, parsePath(tt.path)) + test.AssertResultComplex(t, tt.expectedPaths, ParsePath(tt.path)) } } @@ -37,7 +38,7 @@ var nextYamlPathTests = []struct { func TestNextYamlPath(t *testing.T) { for _, tt := range nextYamlPathTests { var element, remaining = nextYamlPath(tt.path) - assertResultWithContext(t, tt.expectedElement, element, tt) - assertResultWithContext(t, tt.expectedRemaining, remaining, tt) + test.AssertResultWithContext(t, tt.expectedElement, element, tt) + test.AssertResultWithContext(t, tt.expectedRemaining, remaining, tt) } } diff --git a/pkg/yqlib/yaml_converter.go b/pkg/yqlib/yaml_converter.go new file mode 100644 index 00000000..08eec179 --- /dev/null +++ b/pkg/yqlib/yaml_converter.go @@ -0,0 +1,32 @@ +package yqlib + +import ( + yaml "github.com/mikefarah/yaml/v2" + errors "github.com/pkg/errors" + "strings" +) + +func YamlToString(context interface{}, trimOutput bool) (string, error) { + switch context := context.(type) { + case string: + return context, nil + default: + return marshalContext(context, trimOutput) + } +} + +func marshalContext(context interface{}, trimOutput bool) (string, error) { + out, err := yaml.Marshal(context) + + if err != nil { + return "", errors.Wrap(err, "error printing yaml") + } + + outStr := string(out) + // trim the trailing new line as it's easier for a script to add + // it in if required than to remove it + if trimOutput { + return strings.Trim(outStr, "\n "), nil + } + return outStr, nil +} \ No newline at end of file diff --git a/utils_test.go b/test/utils.go similarity index 76% rename from utils_test.go rename to test/utils.go index c4878d95..490ce543 100644 --- a/utils_test.go +++ b/test/utils.go @@ -1,4 +1,4 @@ -package main +package test import ( "bytes" @@ -19,7 +19,7 @@ type resulter struct { Command *cobra.Command } -func runCmd(c *cobra.Command, input string) resulter { +func RunCmd(c *cobra.Command, input string) resulter { buf := new(bytes.Buffer) c.SetOutput(buf) c.SetArgs(strings.Split(input, " ")) @@ -30,7 +30,7 @@ func runCmd(c *cobra.Command, input string) resulter { return resulter{err, output, c} } -func parseData(rawData string) yaml.MapSlice { +func ParseData(rawData string) yaml.MapSlice { var parsedData yaml.MapSlice err := yaml.Unmarshal([]byte(rawData), &parsedData) if err != nil { @@ -40,21 +40,21 @@ func parseData(rawData string) yaml.MapSlice { return parsedData } -func assertResult(t *testing.T, expectedValue interface{}, actualValue interface{}) { +func AssertResult(t *testing.T, expectedValue interface{}, actualValue interface{}) { t.Helper() if expectedValue != actualValue { t.Error("Expected <", expectedValue, "> but got <", actualValue, ">", fmt.Sprintf("%T", actualValue)) } } -func assertResultComplex(t *testing.T, expectedValue interface{}, actualValue interface{}) { +func AssertResultComplex(t *testing.T, expectedValue interface{}, actualValue interface{}) { t.Helper() if !reflect.DeepEqual(expectedValue, actualValue) { t.Error("Expected <", expectedValue, "> but got <", actualValue, ">", fmt.Sprintf("%T", actualValue)) } } -func assertResultWithContext(t *testing.T, expectedValue interface{}, actualValue interface{}, context interface{}) { +func AssertResultWithContext(t *testing.T, expectedValue interface{}, actualValue interface{}, context interface{}) { t.Helper() if expectedValue != actualValue { t.Error(context) @@ -62,7 +62,7 @@ func assertResultWithContext(t *testing.T, expectedValue interface{}, actualValu } } -func writeTempYamlFile(content string) string { +func WriteTempYamlFile(content string) string { tmpfile, _ := ioutil.TempFile("", "testyaml") defer func() { _ = tmpfile.Close() @@ -72,11 +72,11 @@ func writeTempYamlFile(content string) string { return tmpfile.Name() } -func readTempYamlFile(name string) string { +func ReadTempYamlFile(name string) string { content, _ := ioutil.ReadFile(name) return string(content) } -func removeTempYamlFile(name string) { +func RemoveTempYamlFile(name string) { _ = os.Remove(name) } diff --git a/yq.go b/yq.go index c59128f1..c065edca 100644 --- a/yq.go +++ b/yq.go @@ -9,6 +9,7 @@ import ( "reflect" "strconv" "strings" + "github.com/mikefarah/yq/pkg/yqlib" errors "github.com/pkg/errors" @@ -38,6 +39,7 @@ func main() { } func newCommandCLI() *cobra.Command { + yqlib.SetLogger(log) yaml.DefaultMapType = reflect.TypeOf(yaml.MapSlice{}) var rootCmd = &cobra.Command{ Use: "yq", @@ -270,12 +272,18 @@ func readProperty(cmd *cobra.Command, args []string) error { log.Debugf("processing %v - requested index %v", currentIndex, docIndexInt) if updateAll || currentIndex == docIndexInt { log.Debugf("reading %v in index %v", path, currentIndex) - mappedDoc, errorParsing := readPath(dataBucket, path) - log.Debugf("%v", mappedDoc) - if errorParsing != nil { - return errors.Wrapf(errorParsing, "Error reading path in document index %v", currentIndex) + if path == "" { + log.Debug("no path") + log.Debugf("%v", dataBucket) + mappedDocs = append(mappedDocs, dataBucket) + } else { + mappedDoc, errorParsing := yqlib.ReadPath(dataBucket, path) + log.Debugf("%v", mappedDoc) + if errorParsing != nil { + return errors.Wrapf(errorParsing, "Error reading path in document index %v", currentIndex) + } + mappedDocs = append(mappedDocs, mappedDoc) } - mappedDocs = append(mappedDocs, mappedDoc) } currentIndex = currentIndex + 1 } @@ -299,15 +307,6 @@ func readProperty(cmd *cobra.Command, args []string) error { return nil } -func readPath(dataBucket interface{}, path string) (interface{}, error) { - if path == "" { - log.Debug("no path") - return dataBucket, nil - } - var paths = parsePath(path) - return recurse(dataBucket, paths[0], paths[1:]) -} - func newProperty(cmd *cobra.Command, args []string) error { updatedData, err := newYaml(args) if err != nil { @@ -339,8 +338,7 @@ func newYaml(args []string) (interface{}, error) { path := entry.Key.(string) value := entry.Value log.Debugf("setting %v to %v", path, value) - var paths = parsePath(path) - dataBucket = updatedChildValue(dataBucket, paths, value) + dataBucket = yqlib.WritePath(dataBucket, path, value) } return dataBucket, nil @@ -416,8 +414,7 @@ func writeProperty(cmd *cobra.Command, args []string) error { path := entry.Key.(string) value := entry.Value log.Debugf("setting %v to %v", path, value) - var paths = parsePath(path) - dataBucket = updatedChildValue(dataBucket, paths, value) + dataBucket = yqlib.WritePath(dataBucket, path, value) } } return dataBucket, nil @@ -429,28 +426,18 @@ func prefixProperty(cmd *cobra.Command, args []string) error { if len(args) != 2 { return errors.New("Must provide ") } + prefixPath := args[1] + var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex() if errorParsingDocIndex != nil { return errorParsingDocIndex } - var paths = parsePath(args[1]) - - // Inverse order - for i := len(paths)/2 - 1; i >= 0; i-- { - opp := len(paths) - 1 - i - paths[i], paths[opp] = paths[opp], paths[i] - } - var updateData = func(dataBucket interface{}, currentIndex int) (interface{}, error) { if updateAll || currentIndex == docIndexInt { - log.Debugf("Prefixing %v to doc %v", paths, currentIndex) - var mapDataBucket = dataBucket - for _, key := range paths { - singlePath := []string{key} - mapDataBucket = updatedChildValue(nil, singlePath, mapDataBucket) - } + log.Debugf("Prefixing %v to doc %v", prefixPath, currentIndex) + var mapDataBucket = yqlib.PrefixPath(dataBucket, prefixPath) return mapDataBucket, nil } return dataBucket, nil @@ -496,7 +483,6 @@ func deleteProperty(cmd *cobra.Command, args []string) error { return errors.New("Must provide ") } var deletePath = args[1] - var paths = parsePath(deletePath) var updateAll, docIndexInt, errorParsingDocIndex = parseDocumentIndex() if errorParsingDocIndex != nil { return errorParsingDocIndex @@ -505,7 +491,7 @@ func deleteProperty(cmd *cobra.Command, args []string) error { var updateData = func(dataBucket interface{}, currentIndex int) (interface{}, error) { if updateAll || currentIndex == docIndexInt { log.Debugf("Deleting path in doc %v", currentIndex) - return deleteChildValue(dataBucket, paths) + return yqlib.DeletePath(dataBucket, deletePath) } return dataBucket, nil } @@ -532,7 +518,7 @@ func mergeProperties(cmd *cobra.Command, args []string) error { // map var mapDataBucket = make(map[interface{}]interface{}) mapDataBucket["root"] = dataBucket - if err := merge(&mergedData, mapDataBucket, overwriteFlag, appendFlag); err != nil { + if err := yqlib.Merge(&mergedData, mapDataBucket, overwriteFlag, appendFlag); err != nil { return nil, err } for _, f := range filesToMerge { @@ -544,7 +530,7 @@ func mergeProperties(cmd *cobra.Command, args []string) error { return nil, err } mapDataBucket["root"] = fileToMerge - if err := merge(&mergedData, mapDataBucket, overwriteFlag, appendFlag); err != nil { + if err := yqlib.Merge(&mergedData, mapDataBucket, overwriteFlag, appendFlag); err != nil { return nil, err } } @@ -594,34 +580,9 @@ func parseValue(argument string) interface{} { func toString(context interface{}) (string, error) { if outputToJSON { - return jsonToString(context) + return yqlib.JsonToString(context) } - return yamlToString(context) -} - -func yamlToString(context interface{}) (string, error) { - switch context := context.(type) { - case string: - return context, nil - default: - return marshalContext(context) - } -} - -func marshalContext(context interface{}) (string, error) { - out, err := yaml.Marshal(context) - - if err != nil { - return "", errors.Wrap(err, "error printing yaml") - } - - outStr := string(out) - // trim the trailing new line as it's easier for a script to add - // it in if required than to remove it - if trimOutput { - return strings.Trim(outStr, "\n "), nil - } - return outStr, nil + return yqlib.YamlToString(context, trimOutput) } func safelyRenameFile(from string, to string) { diff --git a/yq_test.go b/yq_test.go index 0701c8e0..21d816bf 100644 --- a/yq_test.go +++ b/yq_test.go @@ -4,6 +4,8 @@ import ( "fmt" "runtime" "testing" + "github.com/mikefarah/yq/test" + "github.com/mikefarah/yq/pkg/yqlib" ) var parseValueTests = []struct { @@ -20,7 +22,7 @@ var parseValueTests = []struct { func TestParseValue(t *testing.T) { for _, tt := range parseValueTests { - assertResultWithContext(t, tt.expectedResult, parseValue(tt.argument), tt.testDescription) + test.AssertResultWithContext(t, tt.expectedResult, parseValue(tt.argument), tt.testDescription) } } @@ -28,14 +30,14 @@ func TestMultilineString(t *testing.T) { testString := ` abcd efg` - formattedResult, _ := yamlToString(testString) - assertResult(t, testString, formattedResult) + formattedResult, _ := yqlib.YamlToString(testString, false) + test.AssertResult(t, testString, formattedResult) } func TestNewYaml(t *testing.T) { result, _ := newYaml([]string{"b.c", "3"}) formattedResult := fmt.Sprintf("%v", result) - assertResult(t, + test.AssertResult(t, "[{b [{c 3}]}]", formattedResult) } @@ -43,7 +45,7 @@ func TestNewYaml(t *testing.T) { func TestNewYamlArray(t *testing.T) { result, _ := newYaml([]string{"[0].cat", "meow"}) formattedResult := fmt.Sprintf("%v", result) - assertResult(t, + test.AssertResult(t, "[[{cat meow}]]", formattedResult) } @@ -55,8 +57,8 @@ func TestNewYaml_WithScript(t *testing.T) { e: - name: Mike Farah` result, _ := newYaml([]string{""}) - actualResult, _ := yamlToString(result) - assertResult(t, expectedResult, actualResult) + actualResult, _ := yqlib.YamlToString(result, true) + test.AssertResult(t, expectedResult, actualResult) } func TestNewYaml_WithUnknownScript(t *testing.T) { @@ -71,5 +73,5 @@ func TestNewYaml_WithUnknownScript(t *testing.T) { } else { expectedOutput = `open fake-unknown: no such file or directory` } - assertResult(t, expectedOutput, err.Error()) + test.AssertResult(t, expectedOutput, err.Error()) }