diff options
author | Cameron Moore <moorereason@gmail.com> | 2016-12-27 00:23:20 +0300 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2017-03-11 19:52:25 +0300 |
commit | f039e3be9e4a11808508c8cd3043b340deea040f (patch) | |
tree | df3e709fc6321fd2a3e1d23efa2c3512d8ed4a94 /parser/frontmatter_test.go | |
parent | ddc8cc0082965143a650052a9aa538bac9133481 (diff) |
parser: Refactor frontmatter parser and add tests
Lots of cleanups here:
- Refactor InterfaceToConfig and InterfaceToFrontMatter to use io.Writer.
- Simplify InterfaceToFrontMatter by wrapping InterfaceToConfig.
- Export FrontmatterType since we return it in DetectFrontMatter.
- Refactor removeTOMLIdentifier to avoid blindly replacing "+++".
- Update HandleJSONMetaData to return an empty map on nil input.
- Updates vendored goorgeous package and test for org-mode frontmatter.
- Add tests and godoc comments.
Coverage for parser package increased from 45.2% to 85.2%.
Diffstat (limited to 'parser/frontmatter_test.go')
-rw-r--r-- | parser/frontmatter_test.go | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/parser/frontmatter_test.go b/parser/frontmatter_test.go index 081910094..5aef3562f 100644 --- a/parser/frontmatter_test.go +++ b/parser/frontmatter_test.go @@ -14,9 +14,231 @@ package parser import ( + "bytes" + "reflect" "testing" ) +func TestInterfaceToConfig(t *testing.T) { + cases := []struct { + input interface{} + mark byte + want []byte + isErr bool + }{ + // TOML + {map[string]interface{}{}, TOMLLead[0], nil, false}, + { + map[string]interface{}{"title": "test 1"}, + TOMLLead[0], + []byte("title = \"test 1\"\n"), + false, + }, + + // YAML + {map[string]interface{}{}, YAMLLead[0], []byte("{}\n"), false}, + { + map[string]interface{}{"title": "test 1"}, + YAMLLead[0], + []byte("title: test 1\n"), + false, + }, + + // JSON + {map[string]interface{}{}, JSONLead[0], []byte("{}\n"), false}, + { + map[string]interface{}{"title": "test 1"}, + JSONLead[0], + []byte("{\n \"title\": \"test 1\"\n}\n"), + false, + }, + + // Errors + {nil, TOMLLead[0], nil, true}, + {map[string]interface{}{}, '$', nil, true}, + } + + for i, c := range cases { + var buf bytes.Buffer + + err := InterfaceToConfig(c.input, rune(c.mark), &buf) + if err != nil { + if c.isErr { + continue + } + t.Fatalf("[%d] unexpected error value: %v", i, err) + } + + if !reflect.DeepEqual(buf.Bytes(), c.want) { + t.Errorf("[%d] not equal:\nwant %q,\n got %q", i, c.want, buf.Bytes()) + } + } +} + +func TestInterfaceToFrontMatter(t *testing.T) { + cases := []struct { + input interface{} + mark rune + want []byte + isErr bool + }{ + // TOML + {map[string]interface{}{}, '+', []byte("+++\n\n+++\n"), false}, + { + map[string]interface{}{"title": "test 1"}, + '+', + []byte("+++\ntitle = \"test 1\"\n\n+++\n"), + false, + }, + + // YAML + {map[string]interface{}{}, '-', []byte("---\n{}\n---\n"), false}, // + { + map[string]interface{}{"title": "test 1"}, + '-', + []byte("---\ntitle: test 1\n---\n"), + false, + }, + + // JSON + {map[string]interface{}{}, '{', []byte("{}\n"), false}, + { + map[string]interface{}{"title": "test 1"}, + '{', + []byte("{\n \"title\": \"test 1\"\n}\n"), + false, + }, + + // Errors + {nil, '+', nil, true}, + {map[string]interface{}{}, '$', nil, true}, + } + + for i, c := range cases { + var buf bytes.Buffer + err := InterfaceToFrontMatter(c.input, c.mark, &buf) + if err != nil { + if c.isErr { + continue + } + t.Fatalf("[%d] unexpected error value: %v", i, err) + } + + if !reflect.DeepEqual(buf.Bytes(), c.want) { + t.Errorf("[%d] not equal:\nwant %q,\n got %q", i, c.want, buf.Bytes()) + } + } +} + +func TestHandleTOMLMetaData(t *testing.T) { + cases := []struct { + input []byte + want interface{} + isErr bool + }{ + {nil, map[string]interface{}{}, false}, + {[]byte("title = \"test 1\""), map[string]interface{}{"title": "test 1"}, false}, + {[]byte("a = [1, 2, 3]"), map[string]interface{}{"a": []interface{}{int64(1), int64(2), int64(3)}}, false}, + {[]byte("b = [\n[1, 2],\n[3, 4]\n]"), map[string]interface{}{"b": []interface{}{[]interface{}{int64(1), int64(2)}, []interface{}{int64(3), int64(4)}}}, false}, + // errors + {[]byte("z = [\n[1, 2]\n[3, 4]\n]"), nil, true}, + } + + for i, c := range cases { + res, err := HandleTOMLMetaData(c.input) + if err != nil { + if c.isErr { + continue + } + t.Fatalf("[%d] unexpected error value: %v", i, err) + } + + if !reflect.DeepEqual(res, c.want) { + t.Errorf("[%d] not equal: given %q\nwant %#v,\n got %#v", i, c.input, c.want, res) + } + } +} + +func TestHandleYAMLMetaData(t *testing.T) { + cases := []struct { + input []byte + want interface{} + isErr bool + }{ + {nil, map[string]interface{}{}, false}, + {[]byte("title: test 1"), map[string]interface{}{"title": "test 1"}, false}, + {[]byte("a: Easy!\nb:\n c: 2\n d: [3, 4]"), map[string]interface{}{"a": "Easy!", "b": map[interface{}]interface{}{"c": 2, "d": []interface{}{3, 4}}}, false}, + // errors + {[]byte("z = not toml"), nil, true}, + } + + for i, c := range cases { + res, err := HandleYAMLMetaData(c.input) + if err != nil { + if c.isErr { + continue + } + t.Fatalf("[%d] unexpected error value: %v", i, err) + } + + if !reflect.DeepEqual(res, c.want) { + t.Errorf("[%d] not equal: given %q\nwant %#v,\n got %#v", i, c.input, c.want, res) + } + } +} + +func TestHandleJSONMetaData(t *testing.T) { + cases := []struct { + input []byte + want interface{} + isErr bool + }{ + {nil, map[string]interface{}{}, false}, + {[]byte("{\"title\": \"test 1\"}"), map[string]interface{}{"title": "test 1"}, false}, + // errors + {[]byte("{noquotes}"), nil, true}, + } + + for i, c := range cases { + res, err := HandleJSONMetaData(c.input) + if err != nil { + if c.isErr { + continue + } + t.Fatalf("[%d] unexpected error value: %v", i, err) + } + + if !reflect.DeepEqual(res, c.want) { + t.Errorf("[%d] not equal: given %q\nwant %#v,\n got %#v", i, c.input, c.want, res) + } + } +} + +func TestHandleOrgMetaData(t *testing.T) { + cases := []struct { + input []byte + want interface{} + isErr bool + }{ + {nil, map[string]interface{}{}, false}, + {[]byte("#+title: test 1\n"), map[string]interface{}{"title": "test 1"}, false}, + } + + for i, c := range cases { + res, err := HandleOrgMetaData(c.input) + if err != nil { + if c.isErr { + continue + } + t.Fatalf("[%d] unexpected error value: %v", i, err) + } + + if !reflect.DeepEqual(res, c.want) { + t.Errorf("[%d] not equal: given %q\nwant %#v,\n got %#v", i, c.input, c.want, res) + } + } +} + func TestFormatToLeadRune(t *testing.T) { for i, this := range []struct { kind string @@ -25,8 +247,10 @@ func TestFormatToLeadRune(t *testing.T) { {"yaml", '-'}, {"yml", '-'}, {"toml", '+'}, + {"tml", '+'}, {"json", '{'}, {"js", '{'}, + {"org", '#'}, {"unknown", '+'}, } { result := FormatToLeadRune(this.kind) @@ -36,3 +260,60 @@ func TestFormatToLeadRune(t *testing.T) { } } } + +func TestDetectFrontMatter(t *testing.T) { + cases := []struct { + mark rune + want *FrontmatterType + }{ + // funcs are uncomparable, so we ignore FrontmatterType.Parse in these tests + {'-', &FrontmatterType{nil, []byte(YAMLDelim), []byte(YAMLDelim), false}}, + {'+', &FrontmatterType{nil, []byte(TOMLDelim), []byte(TOMLDelim), false}}, + {'{', &FrontmatterType{nil, []byte("{"), []byte("}"), true}}, + {'#', &FrontmatterType{nil, []byte("#+"), []byte("\n"), false}}, + {'$', nil}, + } + + for _, c := range cases { + res := DetectFrontMatter(c.mark) + if res == nil { + if c.want == nil { + continue + } + + t.Fatalf("want %v, got %v", *c.want, res) + } + + if !reflect.DeepEqual(res.markstart, c.want.markstart) { + t.Errorf("markstart mismatch: want %v, got %v", c.want.markstart, res.markstart) + } + if !reflect.DeepEqual(res.markend, c.want.markend) { + t.Errorf("markend mismatch: want %v, got %v", c.want.markend, res.markend) + } + if !reflect.DeepEqual(res.includeMark, c.want.includeMark) { + t.Errorf("includeMark mismatch: want %v, got %v", c.want.includeMark, res.includeMark) + } + } +} + +func TestRemoveTOMLIdentifier(t *testing.T) { + cases := []struct { + input string + want string + }{ + {"a = 1", "a = 1"}, + {"a = 1\r\n", "a = 1\r\n"}, + {"+++\r\na = 1\r\n+++\r\n", "a = 1\r\n"}, + {"+++\na = 1\n+++\n", "a = 1\n"}, + {"+++\nb = \"+++ oops +++\"\n+++\n", "b = \"+++ oops +++\"\n"}, + {"+++\nc = \"\"\"+++\noops\n+++\n\"\"\"\"\n+++\n", "c = \"\"\"+++\noops\n+++\n\"\"\"\"\n"}, + {"+++\nd = 1\n+++", "d = 1\n"}, + } + + for i, c := range cases { + res := removeTOMLIdentifier([]byte(c.input)) + if string(res) != c.want { + t.Errorf("[%d] given %q\nwant: %q\n got: %q", i, c.input, c.want, res) + } + } +} |