-
-
Notifications
You must be signed in to change notification settings - Fork 347
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow YAML for human-edited metadata
- Loading branch information
Showing
10 changed files
with
261 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
using System.IO; | ||
using System.Linq; | ||
using log4net; | ||
using YamlDotNet.RepresentationModel; | ||
using Newtonsoft.Json.Linq; | ||
|
||
namespace CKAN.NetKAN.Extensions | ||
{ | ||
internal static class YamlExtensions | ||
{ | ||
public static YamlMappingNode Parse(string input) | ||
{ | ||
return Parse(new StringReader(input)); | ||
} | ||
|
||
public static YamlMappingNode Parse(TextReader input) | ||
{ | ||
var stream = new YamlStream(); | ||
stream.Load(input); | ||
return stream.Documents.FirstOrDefault()?.RootNode as YamlMappingNode; | ||
} | ||
|
||
/// <summary> | ||
/// Convert a YAML object to a JSON object | ||
/// </summary> | ||
/// <param name="yaml">The input object</param> | ||
/// <returns> | ||
/// A JObject representation of the input data | ||
/// </returns> | ||
public static JObject ToJObject(this YamlMappingNode yaml) | ||
{ | ||
var jobj = new JObject(); | ||
foreach (var kvp in yaml) | ||
{ | ||
switch (kvp.Value.NodeType) | ||
{ | ||
case YamlNodeType.Mapping: | ||
jobj.Add((string)kvp.Key, (kvp.Value as YamlMappingNode).ToJObject()); | ||
break; | ||
case YamlNodeType.Sequence: | ||
jobj.Add((string)kvp.Key, (kvp.Value as YamlSequenceNode).ToJarray()); | ||
break; | ||
case YamlNodeType.Scalar: | ||
jobj.Add((string)kvp.Key, (kvp.Value as YamlScalarNode).ToJValue()); | ||
break; | ||
} | ||
} | ||
return jobj; | ||
} | ||
|
||
private static JArray ToJarray(this YamlSequenceNode yaml) | ||
{ | ||
var jarr = new JArray(); | ||
foreach (var elt in yaml) | ||
{ | ||
switch (elt.NodeType) | ||
{ | ||
case YamlNodeType.Mapping: | ||
jarr.Add((elt as YamlMappingNode).ToJObject()); | ||
break; | ||
case YamlNodeType.Sequence: | ||
jarr.Add((elt as YamlSequenceNode).ToJarray()); | ||
break; | ||
case YamlNodeType.Scalar: | ||
jarr.Add((elt as YamlScalarNode).ToJValue()); | ||
break; | ||
} | ||
} | ||
return jarr; | ||
} | ||
|
||
private static JValue ToJValue(this YamlScalarNode yaml) | ||
{ | ||
switch (yaml.Value) | ||
{ | ||
case "null": return JValue.CreateNull(); | ||
case "true": return new JValue(true); | ||
case "false": return new JValue(false); | ||
default: return new JValue(yaml.Value); | ||
} | ||
} | ||
|
||
private static readonly ILog log = LogManager.GetLogger(typeof(YamlExtensions)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
using System.Linq; | ||
using NUnit.Framework; | ||
using YamlDotNet.RepresentationModel; | ||
using Newtonsoft.Json.Linq; | ||
|
||
using CKAN.NetKAN.Extensions; | ||
|
||
namespace Tests.NetKAN.Extensions | ||
{ | ||
[TestFixture] | ||
public sealed class YamlExtensionsTests | ||
{ | ||
[Test] | ||
public void Parse_ValidInput_Works() | ||
{ | ||
// Arrange | ||
string input = string.Join("\r\n", new string[] | ||
{ | ||
"spec_version: v1.4", | ||
"identifier: Astrogator", | ||
"$kref: \"#/ckan/github/HebaruSan/Astrogator\"", | ||
"$vref: \"#/ckan/ksp-avc\"", | ||
"license: GPL-3.0", | ||
"tags:", | ||
" - plugin", | ||
" - information", | ||
" - control", | ||
"resources:", | ||
" homepage: https://forum.kerbalspaceprogram.com/index.php?/topic/155998-*", | ||
" bugtracker: https://github.com/HebaruSan/Astrogator/issues", | ||
" repository: https://github.com/HebaruSan/Astrogator", | ||
"recommends:", | ||
" - name: ModuleManager", | ||
" - name: LoadingTipsPlus", | ||
}); | ||
|
||
// Act | ||
YamlMappingNode yaml = YamlExtensions.Parse(input); | ||
|
||
// Assert | ||
Assert.AreEqual("v1.4", (string)yaml["spec_version"]); | ||
Assert.AreEqual("Astrogator", (string)yaml["identifier"]); | ||
Assert.AreEqual("#/ckan/github/HebaruSan/Astrogator", (string)yaml["$kref"]); | ||
Assert.AreEqual("#/ckan/ksp-avc", (string)yaml["$vref"]); | ||
Assert.AreEqual("GPL-3.0", (string)yaml["license"]); | ||
|
||
CollectionAssert.AreEqual( | ||
new string[] { "plugin", "information", "control" }, | ||
(yaml["tags"] as YamlSequenceNode).Children.Select(yn => (string)yn) | ||
); | ||
Assert.AreEqual( | ||
"https://forum.kerbalspaceprogram.com/index.php?/topic/155998-*", | ||
(string)yaml["resources"]["homepage"] | ||
); | ||
Assert.AreEqual( | ||
"https://github.com/HebaruSan/Astrogator/issues", | ||
(string)yaml["resources"]["bugtracker"] | ||
); | ||
Assert.AreEqual( | ||
"https://github.com/HebaruSan/Astrogator", | ||
(string)yaml["resources"]["repository"] | ||
); | ||
Assert.AreEqual("ModuleManager", (string)yaml["recommends"][0]["name"]); | ||
Assert.AreEqual("LoadingTipsPlus", (string)yaml["recommends"][1]["name"]); | ||
} | ||
|
||
[Test] | ||
public void ToJObject_ValidInput_Works() | ||
{ | ||
// Arrange | ||
var yaml = new YamlMappingNode() | ||
{ | ||
{ "spec_version", "v1.4" }, | ||
{ "identifier", "Astrogator" }, | ||
{ "$kref", "#/ckan/github/HebaruSan/Astrogator" }, | ||
{ "$vref", "#/ckan/ksp-avc" }, | ||
{ "license", "GPL-3.0" }, | ||
{ | ||
"tags", | ||
new YamlSequenceNode( | ||
"plugin", | ||
"information", | ||
"control" | ||
) | ||
}, | ||
{ | ||
"resources", | ||
new YamlMappingNode() | ||
{ | ||
{ "homepage", "https://forum.kerbalspaceprogram.com/index.php?/topic/155998-*" }, | ||
{ "bugtracker", "https://github.com/HebaruSan/Astrogator/issues" }, | ||
{ "repository", "https://github.com/HebaruSan/Astrogator" }, | ||
} | ||
}, | ||
{ | ||
"recommends", | ||
new YamlSequenceNode( | ||
new YamlMappingNode() | ||
{ | ||
{ "name", "ModuleManager" } | ||
}, | ||
new YamlMappingNode() | ||
{ | ||
{ "name", "LoadingTipsPlus" } | ||
} | ||
) | ||
} | ||
}; | ||
|
||
// Act | ||
JObject json = yaml.ToJObject(); | ||
|
||
// Assert | ||
Assert.AreEqual("v1.4", (string)json["spec_version"]); | ||
Assert.AreEqual("Astrogator", (string)json["identifier"]); | ||
Assert.AreEqual("#/ckan/github/HebaruSan/Astrogator", (string)json["$kref"]); | ||
Assert.AreEqual("#/ckan/ksp-avc", (string)json["$vref"]); | ||
Assert.AreEqual("GPL-3.0", (string)json["license"]); | ||
|
||
CollectionAssert.AreEqual( | ||
new string[] { "plugin", "information", "control" }, | ||
(json["tags"] as JArray).Select(elt => (string)elt) | ||
); | ||
Assert.AreEqual( | ||
"https://forum.kerbalspaceprogram.com/index.php?/topic/155998-*", | ||
(string)json["resources"]["homepage"] | ||
); | ||
Assert.AreEqual( | ||
"https://github.com/HebaruSan/Astrogator/issues", | ||
(string)json["resources"]["bugtracker"] | ||
); | ||
Assert.AreEqual( | ||
"https://github.com/HebaruSan/Astrogator", | ||
(string)json["resources"]["repository"] | ||
); | ||
Assert.AreEqual("ModuleManager", (string)json["recommends"][0]["name"]); | ||
Assert.AreEqual("LoadingTipsPlus", (string)json["recommends"][1]["name"]); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters