More goccy progress

This commit is contained in:
Mike Farah 2025-06-07 15:23:38 +10:00
parent 58e0cd2600
commit b84fd47934
7 changed files with 274 additions and 239 deletions

View File

@ -69,6 +69,9 @@ func (o *CandidateNode) UnmarshalGoccyYAML(node ast.Node, cm yaml.CommentMap, an
o.Kind = ScalarNode o.Kind = ScalarNode
o.Tag = "!!null" o.Tag = "!!null"
o.Value = node.GetToken().Value o.Value = node.GetToken().Value
if node.GetToken().Type == goccyToken.ImplicitNullType {
o.Value = ""
}
case ast.StringType: case ast.StringType:
o.Kind = ScalarNode o.Kind = ScalarNode
o.Tag = "!!str" o.Tag = "!!str"
@ -112,7 +115,7 @@ func (o *CandidateNode) UnmarshalGoccyYAML(node ast.Node, cm yaml.CommentMap, an
for _, mappingValueNode := range mappingNode.Values { for _, mappingValueNode := range mappingNode.Values {
err := o.goccyProcessMappingValueNode(mappingValueNode, cm, anchorMap) err := o.goccyProcessMappingValueNode(mappingValueNode, cm, anchorMap)
if err != nil { if err != nil {
return ast.ErrInvalidAnchorName return err
} }
} }
if mappingNode.FootComment != nil { if mappingNode.FootComment != nil {
@ -126,7 +129,7 @@ func (o *CandidateNode) UnmarshalGoccyYAML(node ast.Node, cm yaml.CommentMap, an
mappingValueNode := node.(*ast.MappingValueNode) mappingValueNode := node.(*ast.MappingValueNode)
err := o.goccyProcessMappingValueNode(mappingValueNode, cm, anchorMap) err := o.goccyProcessMappingValueNode(mappingValueNode, cm, anchorMap)
if err != nil { if err != nil {
return ast.ErrInvalidAnchorName return err
} }
case ast.SequenceType: case ast.SequenceType:
log.Debugf("UnmarshalYAML - a sequence node") log.Debugf("UnmarshalYAML - a sequence node")

View File

@ -7,96 +7,96 @@ import (
) )
var goccyYamlFormatScenarios = []formatScenario{ var goccyYamlFormatScenarios = []formatScenario{
// { {
// description: "basic - 3", description: "basic - 3",
// skipDoc: true, skipDoc: true,
// input: "3", input: "3",
// expected: "3\n", expected: "3\n",
// }, },
// { {
// description: "basic - 3.1", description: "basic - 3.1",
// skipDoc: true, skipDoc: true,
// input: "3.1", input: "3.1",
// expected: "3.1\n", expected: "3.1\n",
// }, },
// { {
// description: "basic - mike", description: "basic - mike",
// skipDoc: true, skipDoc: true,
// input: "mike: 3", input: "mike: 3",
// expected: "mike: 3\n", expected: "mike: 3\n",
// }, },
// { {
// description: "basic - map multiple entries", description: "basic - map multiple entries",
// skipDoc: true, skipDoc: true,
// input: "mike: 3\nfred: 12\n", input: "mike: 3\nfred: 12\n",
// expected: "mike: 3\nfred: 12\n", expected: "mike: 3\nfred: 12\n",
// }, },
// { {
// description: "basic - 3.1", description: "basic - 3.1",
// skipDoc: true, skipDoc: true,
// input: "{\n mike: 3\n}", input: "{\n mike: 3\n}",
// expected: "{mike: 3}\n", expected: "{mike: 3}\n",
// }, },
// { {
// description: "basic - tag with number", description: "basic - tag with number",
// skipDoc: true, skipDoc: true,
// input: "mike: !!cat 3", input: "mike: !!cat 3",
// expected: "mike: !!cat 3\n", expected: "mike: !!cat 3\n",
// }, },
// { {
// description: "basic - array of numbers", description: "basic - array of numbers",
// skipDoc: true, skipDoc: true,
// input: "- 3", input: "- 3",
// expected: "- 3\n", expected: "- 3\n",
// }, },
// { {
// description: "basic - single line array", description: "basic - single line array",
// skipDoc: true, skipDoc: true,
// input: "[3]", input: "[3]",
// expected: "[3]\n", expected: "[3]\n",
// }, },
// { {
// description: "basic - plain string", description: "basic - plain string",
// skipDoc: true, skipDoc: true,
// input: `a: meow`, input: `a: meow`,
// expected: "a: meow\n", expected: "a: meow\n",
// }, },
// { {
// description: "basic - double quoted string", description: "basic - double quoted string",
// skipDoc: true, skipDoc: true,
// input: `a: "meow"`, input: `a: "meow"`,
// expected: "a: \"meow\"\n", expected: "a: \"meow\"\n",
// }, },
// { {
// description: "basic - single quoted string", description: "basic - single quoted string",
// skipDoc: true, skipDoc: true,
// input: `a: 'meow'`, input: `a: 'meow'`,
// expected: "a: 'meow'\n", expected: "a: 'meow'\n",
// }, },
// { {
// description: "basic - string block", description: "basic - string block",
// skipDoc: true, skipDoc: true,
// input: "a: |\n meow\n", input: "a: |\n meow\n",
// expected: "a: |\n meow\n", expected: "a: |\n meow\n",
// }, },
// { {
// description: "basic - long string", description: "basic - long string",
// skipDoc: true, skipDoc: true,
// input: "a: the cute cat wrote a long sentence that wasn't wrapped at all.\n", input: "a: the cute cat wrote a long sentence that wasn't wrapped at all.\n",
// expected: "a: the cute cat wrote a long sentence that wasn't wrapped at all.\n", expected: "a: the cute cat wrote a long sentence that wasn't wrapped at all.\n",
// }, },
// { {
// description: "basic - string block", description: "basic - string block",
// skipDoc: true, skipDoc: true,
// input: "a: |-\n meow\n", input: "a: |-\n meow\n",
// expected: "a: |-\n meow\n", expected: "a: |-\n meow\n",
// }, },
// { {
// description: "basic - line comment", description: "basic - line comment",
// skipDoc: true, skipDoc: true,
// input: "a: meow # line comment\n", input: "a: meow # line comment\n",
// expected: "a: meow # line comment\n", expected: "a: meow # line comment\n",
// }, },
// { // {
// description: "basic - head comment", // description: "basic - head comment",
// skipDoc: true, // skipDoc: true,
@ -109,54 +109,54 @@ var goccyYamlFormatScenarios = []formatScenario{
// input: "# head comment\na: #line comment\n meow\n", // input: "# head comment\na: #line comment\n meow\n",
// expected: "# head comment\na: meow #line comment\n", // go-yaml does this // expected: "# head comment\na: meow #line comment\n", // go-yaml does this
// }, // },
// { {
// description: "basic - foot comment", description: "basic - foot comment",
// skipDoc: true, skipDoc: true,
// input: "a: meow\n# foot comment\n", input: "a: meow\n# foot comment\n",
// expected: "a: meow\n# foot comment\n", expected: "a: meow\n# foot comment\n",
// }, },
// { {
// description: "basic - foot comment", description: "basic - foot comment",
// skipDoc: true, skipDoc: true,
// input: "a: meow\nb: woof\n# foot comment\n", input: "a: meow\nb: woof\n# foot comment\n",
// expected: "a: meow\nb: woof\n# foot comment\n", expected: "a: meow\nb: woof\n# foot comment\n",
// }, },
// { {
// description: "basic - boolean", description: "basic - boolean",
// skipDoc: true, skipDoc: true,
// input: "true\n", input: "true\n",
// expected: "true\n", expected: "true\n",
// }, },
// { {
// description: "basic - null", description: "basic - null",
// skipDoc: true, skipDoc: true,
// input: "a: null\n", input: "a: null\n",
// expected: "a: null\n", expected: "a: null\n",
// }, },
// { {
// description: "basic - ~", description: "basic - ~",
// skipDoc: true, skipDoc: true,
// input: "a: ~\n", input: "a: ~\n",
// expected: "a: ~\n", expected: "a: ~\n",
// }, },
// { {
// description: "basic - ~", description: "basic - ~",
// skipDoc: true, skipDoc: true,
// input: "null\n", input: "null\n",
// expected: "null\n", expected: "null\n",
// }, },
// { {
// skipDoc: true, skipDoc: true,
// description: "trailing comment", description: "blank value round trip",
// input: "test:", input: "test:",
// expected: "test:", expected: "test:\n",
// }, },
// { {
// skipDoc: true, skipDoc: true,
// description: "trailing comment", description: "trailing comment",
// input: "test: null\n# this comment will be removed", input: "test: null\n# this comment will be removed",
// expected: "test: null\n# this comment will be removed\n", expected: "test: null\n# this comment will be removed\n",
// }, },
// { // {
// description: "doc separator", // description: "doc separator",
// skipDoc: true, // skipDoc: true,
@ -169,106 +169,106 @@ var goccyYamlFormatScenarios = []formatScenario{
// input: "--- cat", // input: "--- cat",
// expected: "---\ncat\n", // expected: "---\ncat\n",
// }, // },
// { {
// description: "scalar with doc separator", description: "scalar with doc separator",
// skipDoc: true, skipDoc: true,
// input: "---cat", input: "---cat",
// expected: "---cat\n", expected: "---cat\n",
// }, },
// { {
// description: "basic - null", description: "basic - null",
// skipDoc: true, skipDoc: true,
// input: "null", input: "null",
// expected: "null\n", expected: "null\n",
// }, },
// { {
// description: "basic - ~", description: "basic - ~",
// skipDoc: true, skipDoc: true,
// input: "~", input: "~",
// expected: "~\n", expected: "~\n",
// }, },
// { {
// description: "octal", description: "octal",
// skipDoc: true, skipDoc: true,
// input: "0o30", input: "0o30",
// expression: "tag", expression: "tag",
// expected: "!!int\n", expected: "!!int\n",
// }, },
// { {
// description: "basic - [null]", description: "basic - [null]",
// skipDoc: true, skipDoc: true,
// input: "[null]", input: "[null]",
// expected: "[null]\n", expected: "[null]\n",
// }, },
// { {
// description: "multi document", description: "multi document",
// skipDoc: true, skipDoc: true,
// input: "a: mike\n---\nb: remember", input: "a: mike\n---\nb: remember",
// expected: "a: mike\n---\nb: remember\n", expected: "a: mike\n---\nb: remember\n",
// }, },
// { {
// description: "single doc anchor map", description: "single doc anchor map",
// skipDoc: true, skipDoc: true,
// input: "a: &remember mike\nb: *remember", input: "a: &remember mike\nb: *remember",
// expected: "a: mike\nb: *remember\n", expected: "a: &remember mike\nb: *remember\n",
// }, },
// { {
// description: "explode doc anchor map", description: "explode doc anchor map",
// skipDoc: true, skipDoc: true,
// input: "a: &remember mike\nb: *remember", input: "a: &remember mike\nb: *remember",
// expression: "explode(.)", expression: "explode(.)",
// expected: "a: mike\nb: mike\n", expected: "a: mike\nb: mike\n",
// }, },
// { {
// description: "multi document anchor map", description: "multi document anchor map",
// skipDoc: true, skipDoc: true,
// input: "a: &remember mike\n---\nb: *remember", input: "a: &remember mike\n---\nb: *remember",
// expression: "explode(.)", expression: "explode(.)",
// expected: "a: mike\n---\nb: mike\n", expected: "a: mike\n---\nb: mike\n",
// }, },
// { {
// description: "merge anchor", description: "merge anchor",
// skipDoc: true, skipDoc: true,
// input: "a: &remember\n c: mike\nb:\n <<: *remember", input: "a: &remember\n c: mike\nb:\n <<: *remember",
// expected: "a: &remember\n c: mike\nb:\n <<: *remember\n", // fine to have !!merge as that's what the current impl does
// }, expected: "a: &remember\n c: mike\nb:\n !!merge <<: *remember\n",
},
{ {
description: "custom tag", description: "custom tag",
skipDoc: true, skipDoc: true,
input: "a: !cat mike", input: "a: !cat mike",
expected: "a: !cat mike\n", expected: "a: !cat mike\n",
}, },
// { {
// description: "basic - [~]", description: "basic - [~]",
// skipDoc: true, skipDoc: true,
// input: "[~]", input: "[~]",
// expected: "[~]\n", expected: "[~]\n",
// }, },
// { {
// description: "basic - null map value", description: "basic - null map value",
// skipDoc: true, skipDoc: true,
// input: "a: null", input: "a: null",
// expected: "a: null\n", expected: "a: null\n",
// }, },
// { {
// description: "basic - number", description: "basic - number",
// skipDoc: true, skipDoc: true,
// input: "3", input: "3",
// expected: "3\n", expected: "3\n",
// }, },
// { {
// description: "basic - float", description: "basic - float",
// skipDoc: true, skipDoc: true,
// input: "3.1", input: "3.1",
// expected: "3.1\n", expected: "3.1\n",
// }, },
// { {
// description: "basic - float", description: "basic - float",
// skipDoc: true, skipDoc: true,
// input: "[1, 2]", input: "[1, 2]",
// expected: "[1, 2]\n", expected: "[1, 2]\n",
// }, },
} }
func testGoccyYamlScenario(t *testing.T, s formatScenario) { func testGoccyYamlScenario(t *testing.T, s formatScenario) {

View File

@ -223,9 +223,20 @@ var anchorOperatorScenarios = []expressionScenario{
"D0, P[], (!!map)::a: mike\n", "D0, P[], (!!map)::a: mike\n",
}, },
}, },
{
description: "Explode with alias keys",
subdescription: "No space between alias",
skipDoc: true,
document: `{f : {a: &a cat, *a: b}}`,
expression: `explode(.f)`,
expected: []string{
"D0, P[], (!!map)::{f: {a: cat, cat: b}}\n",
},
skipForGoccy: true, // can't handle no space between alias
},
{ {
description: "Explode with alias keys", description: "Explode with alias keys",
document: `{f : {a: &a cat, *a: b}}`, document: `{f : {a: &a cat, *a : b}}`,
expression: `explode(.f)`, expression: `explode(.f)`,
expected: []string{ expected: []string{
"D0, P[], (!!map)::{f: {a: cat, cat: b}}\n", "D0, P[], (!!map)::{f: {a: cat, cat: b}}\n",

View File

@ -47,10 +47,10 @@ var styleOperatorScenarios = []expressionScenario{
}, },
{ {
skipDoc: true, skipDoc: true,
document: "bing: &foo frog\na:\n c: cat\n <<: [*foo]", document: "bing: &foo {x: z}\na:\n c: cat\n <<: [*foo]",
expression: `(... | select(tag=="!!str")) style="single"`, expression: `(... | select(tag=="!!str")) style="single"`,
expected: []string{ expected: []string{
"D0, P[], (!!map)::'bing': &foo 'frog'\n'a':\n 'c': 'cat'\n !!merge <<: [*foo]\n", "D0, P[], (!!map)::'bing': &foo {'x': 'z'}\n'a':\n 'c': 'cat'\n !!merge <<: [*foo]\n",
}, },
}, },
{ {

View File

@ -43,6 +43,7 @@ var traversePathOperatorScenarios = []expressionScenario{
expected: []string{ expected: []string{
"D0, P[x], (!!null)::null\n", "D0, P[x], (!!null)::null\n",
}, },
skipForGoccy: true, // throws an error instead, that's fine
}, },
{ {
skipDoc: true, skipDoc: true,
@ -553,6 +554,7 @@ var traversePathOperatorScenarios = []expressionScenario{
document: badAliasSample, document: badAliasSample,
expression: ".steps[]", expression: ".steps[]",
expectedError: "can only use merge anchors with maps (!!map), but got !!seq", expectedError: "can only use merge anchors with maps (!!map), but got !!seq",
skipForGoccy: true, // throws an error on parsing, that's fine
}, },
} }

View File

@ -99,6 +99,7 @@ var uniqueOperatorScenarios = []expressionScenario{
expected: []string{ expected: []string{
"D0, P[], (!!seq)::# abc\n[{name: harry, pet: cat}, {pet: fish}]\n# xyz\n", "D0, P[], (!!seq)::# abc\n[{name: harry, pet: cat}, {pet: fish}]\n# xyz\n",
}, },
skipForGoccy: true, // https://github.com/goccy/go-yaml/issues/757
}, },
} }

View File

@ -29,12 +29,27 @@ type expressionScenario struct {
expectedError string expectedError string
dontFormatInputForDoc bool // dont format input doc for documentation generation dontFormatInputForDoc bool // dont format input doc for documentation generation
requiresFormat string requiresFormat string
skipForGoccy bool
} }
var goccyTesting = false
var testingDecoder = NewYamlDecoder(ConfiguredYamlPreferences)
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
logging.SetLevel(logging.ERROR, "") logging.SetLevel(logging.ERROR, "")
if os.Getenv("DEBUG") == "true" {
logging.SetLevel(logging.DEBUG, "")
}
ConfiguredYamlPreferences.ColorsEnabled = false ConfiguredYamlPreferences.ColorsEnabled = false
ConfiguredJSONPreferences.ColorsEnabled = false ConfiguredJSONPreferences.ColorsEnabled = false
goccyTesting = os.Getenv("GOCCY") == "true"
if goccyTesting {
testingDecoder = NewGoccyYAMLDecoder()
}
Now = func() time.Time { Now = func() time.Time {
return time.Date(2021, time.May, 19, 1, 2, 3, 4, time.UTC) return time.Date(2021, time.May, 19, 1, 2, 3, 4, time.UTC)
} }
@ -53,10 +68,13 @@ func NewSimpleYamlPrinter(writer io.Writer, unwrapScalar bool, indent int, print
func readDocument(content string, fakefilename string, fakeFileIndex int) (*list.List, error) { func readDocument(content string, fakefilename string, fakeFileIndex int) (*list.List, error) {
reader := bufio.NewReader(strings.NewReader(content)) reader := bufio.NewReader(strings.NewReader(content))
return readDocuments(reader, fakefilename, fakeFileIndex, NewYamlDecoder(ConfiguredYamlPreferences)) return readDocuments(reader, fakefilename, fakeFileIndex, testingDecoder)
} }
func testScenario(t *testing.T, s *expressionScenario) { func testScenario(t *testing.T, s *expressionScenario) {
if s.skipForGoccy {
return
}
var err error var err error
node, err := getExpressionParser().ParseExpression(s.expression) node, err := getExpressionParser().ParseExpression(s.expression)
if err != nil { if err != nil {
@ -192,7 +210,7 @@ func formatYaml(yaml string, filename string) string {
panic(err) panic(err)
} }
streamEvaluator := NewStreamEvaluator() streamEvaluator := NewStreamEvaluator()
_, err = streamEvaluator.Evaluate(filename, strings.NewReader(yaml), node, printer, NewYamlDecoder(ConfiguredYamlPreferences)) _, err = streamEvaluator.Evaluate(filename, strings.NewReader(yaml), node, printer, testingDecoder)
if err != nil { if err != nil {
panic(err) panic(err)
} }