More tests

This commit is contained in:
Mike Farah
2026-02-01 10:27:18 +11:00
parent 2be0094729
commit eb04fa87af
7 changed files with 576 additions and 8 deletions
+160
View File
@@ -0,0 +1,160 @@
//go:build !yq_nouri
package yqlib
import (
"io"
"strings"
"testing"
"github.com/mikefarah/yq/v4/test"
)
func TestUriDecoder_Init(t *testing.T) {
decoder := NewUriDecoder()
reader := strings.NewReader("test")
err := decoder.Init(reader)
test.AssertResult(t, nil, err)
}
func TestUriDecoder_DecodeSimpleString(t *testing.T) {
decoder := NewUriDecoder()
reader := strings.NewReader("hello%20world")
err := decoder.Init(reader)
test.AssertResult(t, nil, err)
node, err := decoder.Decode()
test.AssertResult(t, nil, err)
test.AssertResult(t, "!!str", node.Tag)
test.AssertResult(t, "hello world", node.Value)
}
func TestUriDecoder_DecodeSpecialCharacters(t *testing.T) {
decoder := NewUriDecoder()
reader := strings.NewReader("hello%21%40%23%24%25")
err := decoder.Init(reader)
test.AssertResult(t, nil, err)
node, err := decoder.Decode()
test.AssertResult(t, nil, err)
test.AssertResult(t, "hello!@#$%", node.Value)
}
func TestUriDecoder_DecodeUTF8(t *testing.T) {
decoder := NewUriDecoder()
reader := strings.NewReader("%E2%9C%93%20check")
err := decoder.Init(reader)
test.AssertResult(t, nil, err)
node, err := decoder.Decode()
test.AssertResult(t, nil, err)
test.AssertResult(t, "✓ check", node.Value)
}
func TestUriDecoder_DecodePlusSign(t *testing.T) {
decoder := NewUriDecoder()
reader := strings.NewReader("a+b")
err := decoder.Init(reader)
test.AssertResult(t, nil, err)
node, err := decoder.Decode()
test.AssertResult(t, nil, err)
// Note: url.QueryUnescape does NOT convert + to space
// That's only for form encoding (url.ParseQuery)
test.AssertResult(t, "a b", node.Value)
}
func TestUriDecoder_DecodeEmptyString(t *testing.T) {
decoder := NewUriDecoder()
reader := strings.NewReader("")
err := decoder.Init(reader)
test.AssertResult(t, nil, err)
node, err := decoder.Decode()
test.AssertResult(t, nil, err)
test.AssertResult(t, "", node.Value)
// Second decode should return EOF
node, err = decoder.Decode()
test.AssertResult(t, io.EOF, err)
test.AssertResult(t, (*CandidateNode)(nil), node)
}
func TestUriDecoder_DecodeMultipleCalls(t *testing.T) {
decoder := NewUriDecoder()
reader := strings.NewReader("test")
err := decoder.Init(reader)
test.AssertResult(t, nil, err)
// First decode
node, err := decoder.Decode()
test.AssertResult(t, nil, err)
test.AssertResult(t, "test", node.Value)
// Second decode should return EOF since we've consumed all input
node, err = decoder.Decode()
test.AssertResult(t, io.EOF, err)
test.AssertResult(t, (*CandidateNode)(nil), node)
}
func TestUriDecoder_DecodeInvalidEscape(t *testing.T) {
decoder := NewUriDecoder()
reader := strings.NewReader("test%ZZ")
err := decoder.Init(reader)
test.AssertResult(t, nil, err)
_, err = decoder.Decode()
// Should return an error for invalid escape sequence
if err == nil {
t.Error("Expected error for invalid escape sequence, got nil")
}
}
func TestUriDecoder_DecodeSlashAndQuery(t *testing.T) {
decoder := NewUriDecoder()
reader := strings.NewReader("path%2Fto%2Ffile%3Fquery%3Dvalue")
err := decoder.Init(reader)
test.AssertResult(t, nil, err)
node, err := decoder.Decode()
test.AssertResult(t, nil, err)
test.AssertResult(t, "path/to/file?query=value", node.Value)
}
func TestUriDecoder_DecodePercent(t *testing.T) {
decoder := NewUriDecoder()
reader := strings.NewReader("100%25")
err := decoder.Init(reader)
test.AssertResult(t, nil, err)
node, err := decoder.Decode()
test.AssertResult(t, nil, err)
test.AssertResult(t, "100%", node.Value)
}
func TestUriDecoder_DecodeNoEscaping(t *testing.T) {
decoder := NewUriDecoder()
reader := strings.NewReader("simple_text-123")
err := decoder.Init(reader)
test.AssertResult(t, nil, err)
node, err := decoder.Decode()
test.AssertResult(t, nil, err)
test.AssertResult(t, "simple_text-123", node.Value)
}
// Mock reader that returns an error
type errorReader struct{}
func (e *errorReader) Read(_ []byte) (n int, err error) {
return 0, io.ErrUnexpectedEOF
}
func TestUriDecoder_DecodeReadError(t *testing.T) {
decoder := NewUriDecoder()
err := decoder.Init(&errorReader{})
test.AssertResult(t, nil, err)
_, err = decoder.Decode()
test.AssertResult(t, io.ErrUnexpectedEOF, err)
}
+30
View File
@@ -4,6 +4,7 @@ package yqlib
import (
"bufio"
"bytes"
"fmt"
"testing"
@@ -543,6 +544,35 @@ func documentHclRoundTripScenario(w *bufio.Writer, s formatScenario) {
writeOrPanic(w, fmt.Sprintf("```hcl\n%v```\n\n", mustProcessFormatScenario(s, NewHclDecoder(), NewHclEncoder(ConfiguredHclPreferences))))
}
func TestHclEncoderPrintDocumentSeparator(t *testing.T) {
encoder := NewHclEncoder(ConfiguredHclPreferences)
var buf bytes.Buffer
writer := bufio.NewWriter(&buf)
err := encoder.PrintDocumentSeparator(writer)
writer.Flush()
test.AssertResult(t, nil, err)
test.AssertResult(t, "", buf.String())
}
func TestHclEncoderPrintLeadingContent(t *testing.T) {
encoder := NewHclEncoder(ConfiguredHclPreferences)
var buf bytes.Buffer
writer := bufio.NewWriter(&buf)
err := encoder.PrintLeadingContent(writer, "some content")
writer.Flush()
test.AssertResult(t, nil, err)
test.AssertResult(t, "", buf.String())
}
func TestHclEncoderCanHandleAliases(t *testing.T) {
encoder := NewHclEncoder(ConfiguredHclPreferences)
test.AssertResult(t, false, encoder.CanHandleAliases())
}
func TestHclFormatScenarios(t *testing.T) {
for _, tt := range hclFormatScenarios {
testHclScenario(t, tt)
+176
View File
@@ -49,3 +49,179 @@ func TestNodeInfoPrinter_PrintResults(t *testing.T) {
test.AssertResult(t, true, strings.Contains(outStr, "footComment: foot"))
test.AssertResult(t, true, strings.Contains(outStr, "anchor: anchor"))
}
func TestNodeInfoPrinter_PrintedAnything_True(t *testing.T) {
node := &CandidateNode{
Kind: ScalarNode,
Tag: "!!str",
Value: "test",
}
listNodes := list.New()
listNodes.PushBack(node)
var output bytes.Buffer
writer := bufio.NewWriter(&output)
printer := NewNodeInfoPrinter(NewSinglePrinterWriter(writer))
// Before printing, should be false
test.AssertResult(t, false, printer.PrintedAnything())
err := printer.PrintResults(listNodes)
writer.Flush()
if err != nil {
t.Fatalf("PrintResults error: %v", err)
}
// After printing, should be true
test.AssertResult(t, true, printer.PrintedAnything())
}
func TestNodeInfoPrinter_PrintedAnything_False(t *testing.T) {
listNodes := list.New()
var output bytes.Buffer
writer := bufio.NewWriter(&output)
printer := NewNodeInfoPrinter(NewSinglePrinterWriter(writer))
err := printer.PrintResults(listNodes)
writer.Flush()
if err != nil {
t.Fatalf("PrintResults error: %v", err)
}
// No nodes printed, should still be false
test.AssertResult(t, false, printer.PrintedAnything())
}
func TestNodeInfoPrinter_SetNulSepOutput(_ *testing.T) {
var output bytes.Buffer
writer := bufio.NewWriter(&output)
printer := NewNodeInfoPrinter(NewSinglePrinterWriter(writer))
// Should not panic or error
printer.SetNulSepOutput(true)
printer.SetNulSepOutput(false)
}
func TestNodeInfoPrinter_SetAppendix(t *testing.T) {
node := &CandidateNode{
Kind: ScalarNode,
Tag: "!!str",
Value: "test",
}
listNodes := list.New()
listNodes.PushBack(node)
var output bytes.Buffer
writer := bufio.NewWriter(&output)
printer := NewNodeInfoPrinter(NewSinglePrinterWriter(writer))
appendixText := "This is appendix text\n"
appendixReader := strings.NewReader(appendixText)
printer.SetAppendix(appendixReader)
err := printer.PrintResults(listNodes)
writer.Flush()
if err != nil {
t.Fatalf("PrintResults error: %v", err)
}
outStr := output.String()
test.AssertResult(t, true, strings.Contains(outStr, "test"))
test.AssertResult(t, true, strings.Contains(outStr, appendixText))
}
func TestNodeInfoPrinter_MultipleNodes(t *testing.T) {
node1 := &CandidateNode{
Kind: ScalarNode,
Tag: "!!str",
Value: "first",
}
node2 := &CandidateNode{
Kind: ScalarNode,
Tag: "!!str",
Value: "second",
}
listNodes := list.New()
listNodes.PushBack(node1)
listNodes.PushBack(node2)
var output bytes.Buffer
writer := bufio.NewWriter(&output)
printer := NewNodeInfoPrinter(NewSinglePrinterWriter(writer))
err := printer.PrintResults(listNodes)
writer.Flush()
if err != nil {
t.Fatalf("PrintResults error: %v", err)
}
outStr := output.String()
test.AssertResult(t, true, strings.Contains(outStr, "value: first"))
test.AssertResult(t, true, strings.Contains(outStr, "value: second"))
}
func TestNodeInfoPrinter_SequenceNode(t *testing.T) {
node := &CandidateNode{
Kind: SequenceNode,
Tag: "!!seq",
Style: FlowStyle,
}
listNodes := list.New()
listNodes.PushBack(node)
var output bytes.Buffer
writer := bufio.NewWriter(&output)
printer := NewNodeInfoPrinter(NewSinglePrinterWriter(writer))
err := printer.PrintResults(listNodes)
writer.Flush()
if err != nil {
t.Fatalf("PrintResults error: %v", err)
}
outStr := output.String()
test.AssertResult(t, true, strings.Contains(outStr, "kind: SequenceNode"))
test.AssertResult(t, true, strings.Contains(outStr, "tag: '!!seq'"))
test.AssertResult(t, true, strings.Contains(outStr, "style: FlowStyle"))
}
func TestNodeInfoPrinter_MappingNode(t *testing.T) {
node := &CandidateNode{
Kind: MappingNode,
Tag: "!!map",
}
listNodes := list.New()
listNodes.PushBack(node)
var output bytes.Buffer
writer := bufio.NewWriter(&output)
printer := NewNodeInfoPrinter(NewSinglePrinterWriter(writer))
err := printer.PrintResults(listNodes)
writer.Flush()
if err != nil {
t.Fatalf("PrintResults error: %v", err)
}
outStr := output.String()
test.AssertResult(t, true, strings.Contains(outStr, "kind: MappingNode"))
test.AssertResult(t, true, strings.Contains(outStr, "tag: '!!map'"))
}
func TestNodeInfoPrinter_EmptyList(t *testing.T) {
listNodes := list.New()
var output bytes.Buffer
writer := bufio.NewWriter(&output)
printer := NewNodeInfoPrinter(NewSinglePrinterWriter(writer))
err := printer.PrintResults(listNodes)
writer.Flush()
if err != nil {
t.Fatalf("PrintResults error: %v", err)
}
test.AssertResult(t, "", output.String())
test.AssertResult(t, false, printer.PrintedAnything())
}
+48 -2
View File
@@ -230,12 +230,16 @@ name = "Tom" # name comment
// Reproduce bug for https://github.com/mikefarah/yq/issues/2588
// Bug: standalone comments inside a table cause subsequent key-values to be assigned at root.
var issue2588RustToolchainWithComments = `
[owner]
var issue2588RustToolchainWithComments = `[owner]
# comment
name = "Tomer"
`
var tableWithComment = `[owner]
# comment
[things]
`
var sampleFromWeb = `# This is a TOML document
title = "TOML Example"
@@ -574,6 +578,19 @@ var tomlScenarios = []formatScenario{
expected: "null\n",
scenarioType: "decode",
},
{
skipDoc: true,
input: issue2588RustToolchainWithComments,
expected: issue2588RustToolchainWithComments,
scenarioType: "roundtrip",
},
{
skipDoc: true,
input: tableWithComment,
expression: ".owner | headComment",
expected: "comment\n",
scenarioType: "roundtrip",
},
{
description: "Roundtrip: sample from web",
input: sampleFromWeb,
@@ -933,3 +950,32 @@ func TestTomlStringEscapeColourization(t *testing.T) {
})
}
}
func TestTomlEncoderPrintDocumentSeparator(t *testing.T) {
encoder := NewTomlEncoder()
var buf bytes.Buffer
writer := bufio.NewWriter(&buf)
err := encoder.PrintDocumentSeparator(writer)
writer.Flush()
test.AssertResult(t, nil, err)
test.AssertResult(t, "", buf.String())
}
func TestTomlEncoderPrintLeadingContent(t *testing.T) {
encoder := NewTomlEncoder()
var buf bytes.Buffer
writer := bufio.NewWriter(&buf)
err := encoder.PrintLeadingContent(writer, "some content")
writer.Flush()
test.AssertResult(t, nil, err)
test.AssertResult(t, "", buf.String())
}
func TestTomlEncoderCanHandleAliases(t *testing.T) {
encoder := NewTomlEncoder()
test.AssertResult(t, false, encoder.CanHandleAliases())
}