Note Serialization: Handle more edge cases

Apparently parsing a YAML Header + body isn't as trivial as I expected.
This commit is contained in:
Vishesh Handa
2019-12-01 16:30:40 +01:00
parent d2f3f782c7
commit 41526868ff
2 changed files with 64 additions and 19 deletions

View File

@ -46,37 +46,37 @@ class MarkdownYAMLSerializer implements NoteSerializer {
NoteData decode(String str) {
const startYamlStr = "---\n";
const endYamlStr = "\n---\n";
const emptyYamlHeaderStr = "---\n---\n";
const emptyYamlHeaderStr = "---\n---";
if (str.startsWith(emptyYamlHeaderStr)) {
var bodyBeginingPos = emptyYamlHeaderStr.length;
if (str == emptyYamlHeaderStr) {
return NoteData();
}
if (str.startsWith(emptyYamlHeaderStr + "\n")) {
var bodyBeginingPos = emptyYamlHeaderStr.length + 1;
if (str[bodyBeginingPos] == '\n') {
bodyBeginingPos += 1;
}
var body = str.substring(bodyBeginingPos);
return NoteData(body, LinkedHashMap<String, dynamic>());
return NoteData(body);
}
if (str.startsWith(startYamlStr)) {
var endYamlPos = str.indexOf(endYamlStr, startYamlStr.length);
if (endYamlPos == -1) {
return NoteData(str, LinkedHashMap<String, dynamic>());
// Try without the \n in the endYamlStr
const endYamlStrWithoutLineEding = "\n---";
if (str.endsWith(endYamlStrWithoutLineEding)) {
var yamlText =
str.substring(4, str.length - endYamlStrWithoutLineEding.length);
var map = _parseYamlText(yamlText);
return NoteData("", map);
}
return NoteData(str);
}
var yamlText = str.substring(4, endYamlPos);
var map = <String, dynamic>{};
try {
if (yamlText.isNotEmpty) {
var yamlMap = loadYaml(yamlText);
yamlMap.forEach((key, value) {
map[key] = value;
});
}
} catch (err) {
Fimber.d(
'MarkdownYAMLSerializer::decode("$yamlText") -> ${err.toString()}');
}
var map = _parseYamlText(yamlText);
var bodyBeginingPos = endYamlPos + endYamlStr.length;
if (str[bodyBeginingPos] == '\n') {
@ -90,6 +90,25 @@ class MarkdownYAMLSerializer implements NoteSerializer {
return NoteData(str, LinkedHashMap<String, dynamic>());
}
LinkedHashMap<String, dynamic> _parseYamlText(String yamlText) {
LinkedHashMap<String, dynamic> map = LinkedHashMap<String, dynamic>();
if (yamlText.isEmpty) {
return map;
}
try {
var yamlMap = loadYaml(yamlText);
yamlMap.forEach((key, value) {
map[key] = value;
});
} catch (err) {
Fimber.d(
'MarkdownYAMLSerializer::decode("$yamlText") -> ${err.toString()}');
}
return map;
}
@override
String encode(NoteData note) {
if (note.props.isEmpty) {

View File

@ -50,7 +50,7 @@ Alright.""";
expect(actualStr, note.body);
});
test('Markdown Serializer with empty YAML and no \\n', () {
test('Markdown Serializer with empty YAML and no \\n after body', () {
var inputNoteStr = """---
---
Alright.""";
@ -62,6 +62,17 @@ Alright.""";
expect(actualStr, note.body);
});
test('Markdown Serializer with empty YAML and doesn"t end with \\n', () {
var inputNoteStr = """---
---""";
var serializer = MarkdownYAMLSerializer();
var note = serializer.decode(inputNoteStr);
expect("", note.body);
expect(0, note.props.length);
});
test('Markdown Serializer YAML Order', () {
var str = """---
type: Journal
@ -140,5 +151,20 @@ Alright.""";
expect(actualStr, note.body);
});
test('Only YAML Header without \\n', () {
var str = """---
foo: bar
---""";
var serializer = MarkdownYAMLSerializer();
var note = serializer.decode(str);
expect("", note.body);
expect({"foo": "bar"}, note.props);
var actualStr = serializer.encode(note);
expect(actualStr, str + '\n\n');
});
});
}