diff --git a/Directory.Build.props b/Directory.Build.props index ad4c125..4f2867d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,8 +2,9 @@ closure.ch - © 2024-2026 Robert Bill + © 2024-2026 Closure OSS Contributors Robert Bill + MIT true diff --git a/GitVersion.yaml b/GitVersion.yaml index bf21a15..85a2f72 100644 --- a/GitVersion.yaml +++ b/GitVersion.yaml @@ -5,6 +5,7 @@ branches: label: "beta" feature: mode: ContinuousDelivery -assembly-versioning-format: '{MajorMinorPatch}.{WeightedPreReleaseNumber}' +assembly-versioning-format: '{MajorMinorPatch}.0' assembly-file-versioning-format: '{MajorMinorPatch}.{WeightedPreReleaseNumber}' -assembly-informational-format: '{MajorMinorPatch}.{WeightedPreReleaseNumber}' \ No newline at end of file +assembly-informational-format: '{MajorMinorPatch}+{ShortSha}' +commit-date-format: yyyy-MM-ddTHH:mm:ssZ diff --git a/LICENSE b/LICENSE index a0a3f54..169a36f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024-2025 Robert Bill +Copyright (c) 2024-2026 Closure OSS Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/VSyntaxReader.Tests/Parsing/ParsingTest.cs b/VSyntaxReader.Tests/Parsing/ParsingTest.cs index 3725fe6..0e17bcd 100644 --- a/VSyntaxReader.Tests/Parsing/ParsingTest.cs +++ b/VSyntaxReader.Tests/Parsing/ParsingTest.cs @@ -1,4 +1,5 @@ using Calendare.VSyntaxReader.Components; +using Calendare.VSyntaxReader.Properties; using Xunit.Abstractions; namespace VSyntaxReader.Tests.Parsing; @@ -51,6 +52,22 @@ public void ParseFileSimple(string filename, string verificationFilename) } } + [Theory] + [InlineData("wrong-mixed-format.ics", DeserializeErrorCategory.Syntax)] + [InlineData("wrong-file-format.json", DeserializeErrorCategory.WrongFormat)] + [InlineData("wrong-file-format-long.ics", DeserializeErrorCategory.WrongFormat)] + [InlineData("empty.ics", DeserializeErrorCategory.NoContent)] + [InlineData("empty-long.ics", DeserializeErrorCategory.NoContent)] + public void ParseInvalidData(string filename, DeserializeErrorCategory errorCategory) + { + var sourceFilename = FileExtensions.BuildSourceFilename(filename); + var parseResult = Builder.Parser.TryParseFile(sourceFilename, out var vcalendar); + Assert.Null(vcalendar); + Assert.False(parseResult.Success, parseResult.ErrorMessage); + Assert.Equal(errorCategory, parseResult.ErrorCategory); + } + + [Theory] [InlineData("Calendars/Alarm/ALARM1.ics")] [InlineData("Calendars/Alarm/ALARM2.ics")] diff --git a/VSyntaxReader.Tests/Parsing/data/empty-long.ics b/VSyntaxReader.Tests/Parsing/data/empty-long.ics new file mode 100644 index 0000000..69a4569 --- /dev/null +++ b/VSyntaxReader.Tests/Parsing/data/empty-long.ics @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VSyntaxReader.Tests/Parsing/data/wrong-file-format-long.ics b/VSyntaxReader.Tests/Parsing/data/wrong-file-format-long.ics new file mode 100644 index 0000000..b406237 --- /dev/null +++ b/VSyntaxReader.Tests/Parsing/data/wrong-file-format-long.ics @@ -0,0 +1,13 @@ + + + + + + + + + + + + +{ "Calendar": "i'm not" } diff --git a/VSyntaxReader.Tests/Parsing/data/wrong-file-format.json b/VSyntaxReader.Tests/Parsing/data/wrong-file-format.json new file mode 100644 index 0000000..2366afa --- /dev/null +++ b/VSyntaxReader.Tests/Parsing/data/wrong-file-format.json @@ -0,0 +1,3 @@ +{ + "Calendar": "i'm not" +} \ No newline at end of file diff --git a/VSyntaxReader.Tests/Parsing/data/wrong-mixed-format.ics b/VSyntaxReader.Tests/Parsing/data/wrong-mixed-format.ics new file mode 100644 index 0000000..eda715e --- /dev/null +++ b/VSyntaxReader.Tests/Parsing/data/wrong-mixed-format.ics @@ -0,0 +1,20 @@ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:DAVx5/4.4.2-ose ical4j/3.2.19 (at.techbee.jtx) +BEGIN:VTODO +DTSTAMP:20240813T061445Z +UID:02261d66-ea00-4404-a4d6-08e21012534c +SEQUENCE:20 +CREATED:20240813T060745Z +LAST-MODIFIED:20240813T061437Z +SUMMARY:Task in TZ Hongkong +DESCRIPTION:What should I say\, that will give you a good sense of the type + of issues we are facing? +DTSTART;TZID=Hongkong:20240813T151500 +PRIORITY:0 +{ + "Calendar": "i'm not", + "Correct": false +} +END:VTODO +END:VCALENDAR \ No newline at end of file diff --git a/VSyntaxReader.Tests/VSyntaxReader.Tests.csproj b/VSyntaxReader.Tests/VSyntaxReader.Tests.csproj index a4bb19b..380d13b 100644 --- a/VSyntaxReader.Tests/VSyntaxReader.Tests.csproj +++ b/VSyntaxReader.Tests/VSyntaxReader.Tests.csproj @@ -7,7 +7,7 @@ true - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/VSyntaxReader.Tests/packages.lock.json b/VSyntaxReader.Tests/packages.lock.json index 6cd4373..ca79ca9 100644 --- a/VSyntaxReader.Tests/packages.lock.json +++ b/VSyntaxReader.Tests/packages.lock.json @@ -4,9 +4,9 @@ "net10.0": { "coverlet.collector": { "type": "Direct", - "requested": "[10.0.0, )", - "resolved": "10.0.0", - "contentHash": "WFejCcOUR6k8UYyDnnR6Gk+obFYMsWrZuNqPJnsVFGVhpPSN0y20D4qbdKJnXinYGx9PQ397Hf9TnU1NBST8vA==" + "requested": "[10.0.1, )", + "resolved": "10.0.1", + "contentHash": "27jXSV/0DbVqF5jDrAxuQFZ9oaz6gmG03p8ttxAFk+X0M4woFYj7MoWDLCna5EGLb0CE6OE7X6ZH3Wt5smTtaA==" }, "GitVersion.MsBuild": { "type": "Direct", diff --git a/VSyntaxReader/Parsers/CalendarParser.cs b/VSyntaxReader/Parsers/CalendarParser.cs index 4b3dba4..58051cf 100644 --- a/VSyntaxReader/Parsers/CalendarParser.cs +++ b/VSyntaxReader/Parsers/CalendarParser.cs @@ -141,10 +141,11 @@ public DeserializeResult TryParse(Stream fr, [NotNullWhen(true)] out VCalendar? else { vcalendar = null; - return new DeserializeResult(false, $"{line.LineNo:0000}: ERROR {line.Raw} [{line.PhysicalLineCount}-{line.PhysicalLineNo + line.PhysicalLineCount}]"); + var errCategory = line.LineNo != 0 ? DeserializeErrorCategory.Syntax : DeserializeErrorCategory.WrongFormat; + return new DeserializeResult(false, $"{line.LineNo:0000}: ERROR {line.Raw} [{line.PhysicalLineCount}-{line.PhysicalLineNo + line.PhysicalLineCount}]", errCategory); } } lineReader.Close(); - return vcalendar is not null ? new DeserializeResult(true) : new DeserializeResult(false, "Nothing to parse"); + return vcalendar is not null ? new DeserializeResult(true) : new DeserializeResult(false, "Nothing to parse", DeserializeErrorCategory.NoContent); } } diff --git a/VSyntaxReader/Properties/DeserializeResult.cs b/VSyntaxReader/Properties/DeserializeResult.cs index 2ba866f..cba316f 100644 --- a/VSyntaxReader/Properties/DeserializeResult.cs +++ b/VSyntaxReader/Properties/DeserializeResult.cs @@ -1,6 +1,13 @@ namespace Calendare.VSyntaxReader.Properties; -public record DeserializeResult(bool Success, string? ErrorMessage = null) +public enum DeserializeErrorCategory +{ + Syntax, + NoContent, + WrongFormat, +} + +public record DeserializeResult(bool Success, string? ErrorMessage = null, DeserializeErrorCategory ErrorCategory = DeserializeErrorCategory.Syntax) { public static implicit operator bool(DeserializeResult dr) => dr.Success; } diff --git a/VSyntaxReader/Properties/TextProperty.cs b/VSyntaxReader/Properties/TextProperty.cs index 2dbed98..98a7a67 100644 --- a/VSyntaxReader/Properties/TextProperty.cs +++ b/VSyntaxReader/Properties/TextProperty.cs @@ -23,16 +23,15 @@ public string? Value } if (Raw.Parameters.TryFindOneParameter(EncodingParam, out var encoding)) { - switch (encoding.Value) + return encoding.Value switch { - case "BASE64": - return Encoding.UTF8.GetString(Convert.FromBase64String(Raw.Value)); - default: - return null; // NOT VALID AS ENCODING METHOD NOT SUPPORTED - } + "BASE64" => Encoding.UTF8.GetString(Convert.FromBase64String(Raw.Value)), + _ => null,// NOT VALID AS ENCODING METHOD NOT SUPPORTED + }; } return EscapingExtensions.UnescapeText(Raw.Value); } + set { Raw = Raw with { Value = EscapingExtensions.EscapeText(value) }; diff --git a/VSyntaxReader/packages.lock.json b/VSyntaxReader/packages.lock.json index e9c7a9e..720dd4f 100644 --- a/VSyntaxReader/packages.lock.json +++ b/VSyntaxReader/packages.lock.json @@ -16,9 +16,9 @@ }, "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[10.0.7, )", - "resolved": "10.0.7", - "contentHash": "AA/yhzFHNtQZXLdqjzujPy25G8EWwGWsAnxOE2zYSBoT/8QHP6ketN3CToD3DFreO653ipUwnKHo22B8AlBMCw==" + "requested": "[10.0.8, )", + "resolved": "10.0.8", + "contentHash": "dVbSXGIFNR5nZcv2tOLoWI+a9T4jtFd77IYjuND+QVe360qWgAF7H0WtoopYhRw/+SgpGUTyrkrh+65+ClNnfw==" }, "NodaTime": { "type": "Direct", @@ -51,9 +51,9 @@ }, "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[8.0.26, )", - "resolved": "8.0.26", - "contentHash": "o7/yVssM2r9Wyln2s9edBd5ANZXqdSdBI+g7JqXkyJmXrhs2WsJp25K5yPnYrTgdKBCjKB8bg+O2oew4sgzFaA==" + "requested": "[8.0.27, )", + "resolved": "8.0.27", + "contentHash": "rQi9TxifHRnXP7lVRZH05DxD2/XGbJp12q0ozcbrlBlBnyyzssFTH/2vLhtKWUp2CT1qVscTrcYTFiwTyKPKRg==" }, "NodaTime": { "type": "Direct", @@ -86,9 +86,9 @@ }, "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[9.0.15, )", - "resolved": "9.0.15", - "contentHash": "EejcbfCMR77Dthy77qxRbEShmzLApHZUPqXMBVQK+A0pNrRThkaHoGGMGvbq/gTkC/waKcDEgjBkbaejB58Wtw==" + "requested": "[9.0.16, )", + "resolved": "9.0.16", + "contentHash": "ccPBYGLPJt8DeJTUzQ0JzOh/iuUAgnjayU63PokVywAhUOx+dzDKSPTL7AG94U/VpvNXflTT2AjsFAIF1+bXBw==" }, "NodaTime": { "type": "Direct",