From 8386f2f0aef00bf63665bfc15191d7c8e55d8af3 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 19:00:58 +0800 Subject: [PATCH 01/20] Added Interpret Tests + Deterministic Builds --- .github/release-drafter.yml | 9 +- .../EvaluationTests.cs | 26 +++-- CSharpMath.Evaluation.Tests/InterpretTests.cs | 26 +++++ CSharpMath.Evaluation.Tests/PredictTests.cs | 110 +++++++++--------- CSharpMath.Evaluation/Evaluation.cs | 36 +++--- CSharpMath.Evaluation/Interpret.cs | 4 - Directory.Build.props | 5 + ReadMe.md | 2 +- 8 files changed, 119 insertions(+), 99 deletions(-) create mode 100644 CSharpMath.Evaluation.Tests/InterpretTests.cs diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 38d98637..f4de8d36 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -39,12 +39,11 @@ categories: label: 'Type/Housekeeping' # Extra line before $BODY or markdown on the first line of $BODY will be interpreted as plain text change-template: | -
$TITLE (#$NUMBER) @$AUTHOR - +
`$TITLE` (#$NUMBER) @$AUTHOR
+ $BODY - +
no-changes-template: '* (No changes)' replacers: - # We don't support nested and
so we add a (?!
|) - - search: '/
((?:(?!
|).)+?)<\/summary>\s*<\/details>/g' + - search: '/
(.+?)<\/summary>
\s*<\/td><\/table><\/details>/g' replace: '- $1' diff --git a/CSharpMath.Evaluation.Tests/EvaluationTests.cs b/CSharpMath.Evaluation.Tests/EvaluationTests.cs index 0c32c188..b98e20f7 100644 --- a/CSharpMath.Evaluation.Tests/EvaluationTests.cs +++ b/CSharpMath.Evaluation.Tests/EvaluationTests.cs @@ -3,12 +3,12 @@ using Xunit; using AngouriMath; -namespace CSharpMath { +namespace CSharpMath.EvaluationTests { using Atom; - public partial class EvluationTests { - MathList ParseLaTeX(string latex) => + public class EvaluationTests { + internal static MathList ParseLaTeX(string latex) => LaTeXParser.MathListFromLaTeX(latex).Match(list => list, e => throw new Xunit.Sdk.XunitException(e)); - Evaluation.MathItem ParseMath(string latex) => + static Evaluation.MathItem ParseMath(string latex) => Evaluation.Evaluate(ParseLaTeX(latex)).Match(entity => entity, e => throw new Xunit.Sdk.XunitException(e)); void Test(string input, string converted, string? result) { void Test(string input) { @@ -424,7 +424,10 @@ public void Numbers(string input, string converted, string output) => [InlineData(@"\sin^a\ \; (x)^2(x)", @"\sin \left( x\right) ^{a\times 2}\times x", @"\sin \left( x\right) ^{2\times a}\times x")] [InlineData(@"\sin (\frac\pi2)", @"\sin \left( \frac{\pi }{2}\right) ", @"1")] [InlineData(@"\sin (\frac\pi2)+1", @"\sin \left( \frac{\pi }{2}\right) +1", @"2")] - public void Parentheses(string latex, string converted, string result) => Test(latex, converted, result); + public void Parentheses(string latex, string converted, string result) { + Test(latex, converted, result); + Test(latex.Replace('(', '[').Replace(')', ']'), converted, result); + } [Theory] [InlineData(@"\begin{matrix}1\end{matrix}", @"\left( \begin{matrix}1\end{matrix}\right) ", @"\left( \begin{matrix}1\end{matrix}\right) ")] [InlineData(@"\begin{pmatrix}1\end{pmatrix}", @"\left( \begin{matrix}1\end{matrix}\right) ", @"\left( \begin{matrix}1\end{matrix}\right) ")] @@ -580,11 +583,12 @@ public void Numbers(string input, string converted, string output) => [InlineData(@"\left(1+\right]", "Missing right operand for +")] [InlineData(@"\left(2,3\right]^\square", "Placeholders should be filled")] [InlineData(@"(2,3]^\square", "Placeholders should be filled")] - [InlineData(@"[]", "Unrecognized bracket pair [ ]")] - [InlineData(@"[x]", "Unrecognized bracket pair [ ]")] - [InlineData(@"[[x]", "Unrecognized bracket pair [ ]")] - [InlineData(@"[x]]", "Unrecognized bracket pair [ ]")] - [InlineData(@"\left[\right]", "Unrecognized bracket pair [ ]")] + [InlineData(@"[]", "Missing math inside [ ]")] + [InlineData(@"[[x]", "Missing ]")] + [InlineData(@"[x]]", "Missing [")] + [InlineData(@"[_\square x]", "Subscripts are unsupported for Open [")] + [InlineData(@"[x]_\square", "Subscripts are unsupported for Close ]")] + [InlineData(@"\left[\right]", "Missing math inside [ ]")] [InlineData(@"\left[1+\right]", "Missing right operand for +")] [InlineData(@"\left[2,3\right]^\square", "Placeholders should be filled")] [InlineData(@"[2,3]^\square", "Placeholders should be filled")] @@ -633,7 +637,7 @@ public void Numbers(string input, string converted, string output) => [InlineData(@"+(3,4]", "Set cannot be right operand for +")] [InlineData(@"[5,6)\times", "Set cannot be left operand for ×")] [InlineData(@"\frac{[7,8]}{9}", "Set cannot be numerator")] - [InlineData(@"\sqrt[{[]}]{}", "Unrecognized bracket pair [ ]")] + [InlineData(@"\sqrt[{[)}]{}", "Unrecognized bracket pair [ )")] [InlineData(@"\sqrt[{[a,b]}]{}", "Set cannot be degree")] [InlineData(@"\{\{\}\}", "Set cannot be set element")] [InlineData(@"\cap", "Unsupported Unary Operator ∩")] diff --git a/CSharpMath.Evaluation.Tests/InterpretTests.cs b/CSharpMath.Evaluation.Tests/InterpretTests.cs new file mode 100644 index 00000000..10a24b5a --- /dev/null +++ b/CSharpMath.Evaluation.Tests/InterpretTests.cs @@ -0,0 +1,26 @@ +using System; +using System.Linq; +using Xunit; +namespace CSharpMath.EvaluationTests { + public class InterpretTests { + [Theory] + [InlineData(@"", @"\color{red}\text{There is nothing to evaluate}")] + [InlineData(@"1", @"\underline\mathrm{Input}\\1\\\\\underline\mathrm{Simplified}\\1\\\\\underline\mathrm{Value\ (100\ digits)}\\1")] + [InlineData(@"1+", @"\color{red}\text{Missing right operand for +}")] + [InlineData(@"1+2", @"\underline\mathrm{Input}\\1+2\\\\\underline\mathrm{Simplified}\\3\\\\\underline\mathrm{Value\ (100\ digits)}\\3")] + [InlineData(@"1+\sqrt", @"\color{red}\text{Missing radicand}")] + [InlineData(@"1+\sqrt2", @"\underline\mathrm{Input}\\1+\sqrt{2}\\\\\underline\mathrm{Simplified}\\1+\sqrt{2}\\\\\underline\mathrm{Value\ (100\ digits)}\\2.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573")] + [InlineData(@"1+\sqrt{2x}", @"\underline\mathrm{Input}\\1+\sqrt{2\times x_{}}\\\\\underline\mathrm{Simplified}\\1+\sqrt{2\times x_{}}\\\\\underline\mathrm{Expanded}\\1+\sqrt{2\times x_{}}\\\\\underline\mathrm{Factorized}\\1+\sqrt{2\times x_{}}")] + [InlineData(@"1+\sqrt{2xy}", @"\underline\mathrm{Input}\\1+\sqrt{2\times x_{}\times y_{}}\\\\\underline\mathrm{Simplified}\\1+\sqrt{2\times x_{}\times y_{}}\\\\\underline\mathrm{Expanded}\\1+\sqrt{2\times x_{}\times y_{}}\\\\\underline\mathrm{Factorized}\\1+\sqrt{2\times x_{}\times y_{}}")] + [InlineData(@"=1+\sqrt{2xy}", @"\color{red}\text{Missing left side of equation}")] + [InlineData(@"1+\sqrt{2xy}=", @"\color{red}\text{Missing right side of equation}")] + [InlineData(@"1+\sqrt{2xy}=3", @"\underline\mathrm{Input}\\1+\sqrt{2\times x_{}\times y_{}}=3\\\\\underline\mathrm{Solutions}\\x_{}\in \left\{\frac{--\frac{4}{y_{}}}{2}\right\}\\y_{}\in \left\{\frac{4}{2\times x_{}}\right\}\\")] + [InlineData(@"1=3", @"\underline\mathrm{Input}\\1=3\\\\\underline\mathrm{Result}\\\text{False}")] + [InlineData(@"1=1", @"\underline\mathrm{Input}\\1=1\\\\\underline\mathrm{Result}\\\text{True}")] + public void Interpret(string input, string expected) { + var actual = Evaluation.Interpret(EvaluationTests.ParseLaTeX(input)); + Assert.Equal(expected, actual); + Assert.NotEmpty(EvaluationTests.ParseLaTeX(actual)); + } + } +} \ No newline at end of file diff --git a/CSharpMath.Evaluation.Tests/PredictTests.cs b/CSharpMath.Evaluation.Tests/PredictTests.cs index 71e7bd6d..58f549c0 100644 --- a/CSharpMath.Evaluation.Tests/PredictTests.cs +++ b/CSharpMath.Evaluation.Tests/PredictTests.cs @@ -1,62 +1,60 @@ using System; using System.Linq; using Xunit; -namespace CSharpMath { - public partial class EvaluationTests { - public class PredictTests { - [Theory] - [InlineData(1, 1, 1)] - [InlineData(2, 2, 2)] - [InlineData(1, 2, 3, 4)] - [InlineData(3, 4, 5, 6)] - [InlineData(1, 2, 3, 4, 5)] - [InlineData(3, 4, 5, 6, 7)] - [InlineData(1, 3, 5, 7)] - [InlineData(8, 10, 12, 14)] - [InlineData(1, 3, 5, 7, 9)] - [InlineData(8, 10, 12, 14, 16)] - [InlineData(1, 4, 7, 10)] - [InlineData(1, 4, 7, 10, 13)] - [InlineData(24, 31, 38, 45)] - [InlineData(24, 31, 38, 45, 52)] - [InlineData(17, 21, 25, 29)] - [InlineData(17, 21, 25, 29, 33)] - [InlineData(1, 1, 1, 1)] - [InlineData(1, 1, 1, 1, 1)] - [InlineData(1, 3, 1, 3, 1)] - [InlineData(1, 3, 1, 3, 1, 3)] - [InlineData(1, 2, 4, 8)] - [InlineData(1, 2, 4, 8, 16)] - [InlineData(1, 3, 9, 27)] - [InlineData(1, 3, 9, 27, 81)] - [InlineData(1, -2, 4, -8)] - [InlineData(-1, 2, -4, 8)] - [InlineData(30, 31, 40, 41, 50, 51)] - [InlineData(61, 62, 63, 71, 72, 73, 81, 82)] - [InlineData(2, 4, 8, 24, 48, 96, 288, 576, 1152)] - [InlineData(0, 0, 0, 1, 0, 0, 0, 1, 0)] - [InlineData(39, 34, 27, 22, 15, 10)] - [InlineData(39, 34, 27, 22, 15, 10, 3)] - [InlineData(31, 30, 22, 21, 13, 12)] - [InlineData(31, 30, 22, 21, 13, 12, 4)] - // Use int instead of double because https://github.com/xunit/xunit/issues/1670#issuecomment-373566797 - public void Integer(params int[] input) { - static void Test(System.Collections.Generic.IEnumerable seq) => - Assert.Equal(seq.Last(), Assert.IsType(Evaluation.Predict(seq.Select(x => (double)x).SkipLast(1).ToArray())), 12); - Test(input); - Test(input.Reverse()); - } - [Theory] - [InlineData(new int[0])] - [InlineData(1)] - [InlineData(1, 2)] - [InlineData(2, 1)] - [InlineData(1, 2, 1)] - [InlineData(1, 2, 1, 3)] - [InlineData(39, 34, 27, 22)] - [InlineData(31, 30, 22, 21)] - public void IntegerFail(params int[] input) => - Assert.Null(Evaluation.Predict(input.Select(x => (double)x).ToArray())); +namespace CSharpMath.EvaluationTests { + public class PredictTests { + [Theory] + [InlineData(1, 1, 1)] + [InlineData(2, 2, 2)] + [InlineData(1, 2, 3, 4)] + [InlineData(3, 4, 5, 6)] + [InlineData(1, 2, 3, 4, 5)] + [InlineData(3, 4, 5, 6, 7)] + [InlineData(1, 3, 5, 7)] + [InlineData(8, 10, 12, 14)] + [InlineData(1, 3, 5, 7, 9)] + [InlineData(8, 10, 12, 14, 16)] + [InlineData(1, 4, 7, 10)] + [InlineData(1, 4, 7, 10, 13)] + [InlineData(24, 31, 38, 45)] + [InlineData(24, 31, 38, 45, 52)] + [InlineData(17, 21, 25, 29)] + [InlineData(17, 21, 25, 29, 33)] + [InlineData(1, 1, 1, 1)] + [InlineData(1, 1, 1, 1, 1)] + [InlineData(1, 3, 1, 3, 1)] + [InlineData(1, 3, 1, 3, 1, 3)] + [InlineData(1, 2, 4, 8)] + [InlineData(1, 2, 4, 8, 16)] + [InlineData(1, 3, 9, 27)] + [InlineData(1, 3, 9, 27, 81)] + [InlineData(1, -2, 4, -8)] + [InlineData(-1, 2, -4, 8)] + [InlineData(30, 31, 40, 41, 50, 51)] + [InlineData(61, 62, 63, 71, 72, 73, 81, 82)] + [InlineData(2, 4, 8, 24, 48, 96, 288, 576, 1152)] + [InlineData(0, 0, 0, 1, 0, 0, 0, 1, 0)] + [InlineData(39, 34, 27, 22, 15, 10)] + [InlineData(39, 34, 27, 22, 15, 10, 3)] + [InlineData(31, 30, 22, 21, 13, 12)] + [InlineData(31, 30, 22, 21, 13, 12, 4)] + // Use int instead of double because https://github.com/xunit/xunit/issues/1670#issuecomment-373566797 + public void Integer(params int[] input) { + static void Test(System.Collections.Generic.IEnumerable seq) => + Assert.Equal(seq.Last(), Assert.IsType(Evaluation.Predict(seq.Select(x => (double)x).SkipLast(1).ToArray())), 12); + Test(input); + Test(input.Reverse()); } + [Theory] + [InlineData(new int[0])] + [InlineData(1)] + [InlineData(1, 2)] + [InlineData(2, 1)] + [InlineData(1, 2, 1)] + [InlineData(1, 2, 1, 3)] + [InlineData(39, 34, 27, 22)] + [InlineData(31, 30, 22, 21)] + public void IntegerFail(params int[] input) => + Assert.Null(Evaluation.Predict(input.Select(x => (double)x).ToArray())); } } \ No newline at end of file diff --git a/CSharpMath.Evaluation/Evaluation.cs b/CSharpMath.Evaluation/Evaluation.cs index e9cb3e7c..6d8d21e1 100644 --- a/CSharpMath.Evaluation/Evaluation.cs +++ b/CSharpMath.Evaluation/Evaluation.cs @@ -167,8 +167,9 @@ static Result TryMakeSet(MathItem.Comma c, bool leftClosed, bool right _ => "Unrecognized bracket pair ( ]" } }, { ("[", "]"), item => item switch { + null => "Missing math inside [ ]", MathItem.Comma c => TryMakeSet(c, true, true), - _ => "Unrecognized bracket pair [ ]" + _ => item } }, { ("{", "}"), item => item.AsEntities("set element").Bind(entities => (MathItem)MathS.Sets.Finite(entities)) } }; @@ -392,14 +393,18 @@ _ when LaTeXSettings.CommandForAtom(atom) is string s => MathS.Var(s + subscript handlePrecendence = Precedence.SetOperation; handleBinarySet = (l, r) => l - r; goto handleBinarySet; - // Until C# allows declaring variables under "or pattern"s... - case Atoms.Inner { LeftBoundary:{ Nucleus:"[" }, InnerList:{ Count:1 } inner, RightBoundary:{ Nucleus:"]" } } - when inner[0] is Atoms.Table { Environment: "matrix" } table: - var matrix = table; - goto handleMatrix; - case Atoms.Table { Environment: "matrix" } table: - matrix = table; - goto handleMatrix; + case Atoms.Table { Environment: "matrix" } matrix: + var (rows, cols, cells) = (matrix.NRows, matrix.NColumns, matrix.Cells); + var matrixElements = new Entity[rows * cols]; + for (var row = 0; row < rows; row++) + for (var col = 0; col < cols; col++) { + if (cells[row].Count <= col) + return $"There are empty slots in the {rows}×{cols} matrix"; + (matrixElements[row * cols + col], error) = Transform(cells[row][col]).ExpectEntity("matrix element"); + if (error != null) return error; + } + @this = MathS.Matrices.Matrix(rows, cols, matrixElements); + goto handleThis; case Atoms.Open { Nucleus: var opening }: if (!OpenBracketInfo.TryGetValue(opening, out var bracketInfo)) return "Unsupported opening bracket " + opening; @@ -463,19 +468,6 @@ _ when LaTeXSettings.CommandForAtom(atom) is string s => MathS.Var(s + subscript return $"Unsupported table environment {table.Environment}"; default: return $"Unsupported {atom.TypeName} {atom.Nucleus}"; - - handleMatrix: - var (rows, cols, cells) = (matrix.NRows, matrix.NColumns, matrix.Cells); - var matrixElements = new Entity[rows * cols]; - for (var row = 0; row < rows; row++) - for (var col = 0; col < cols; col++) { - if (cells[row].Count <= col) - return $"There are empty slots in the {rows}×{cols} matrix"; - (matrixElements[row * cols + col], error) = Transform(cells[row][col]).ExpectEntity("matrix element"); - if (error != null) return error; - } - @this = MathS.Matrices.Matrix(rows, cols, matrixElements); - goto handleThis; #pragma warning disable CS0162 // Unreachable code detected #pragma warning disable CS0164 // This label has not been referenced handleFunction: diff --git a/CSharpMath.Evaluation/Interpret.cs b/CSharpMath.Evaluation/Interpret.cs index fac7b4f0..8ada8f4c 100644 --- a/CSharpMath.Evaluation/Interpret.cs +++ b/CSharpMath.Evaluation/Interpret.cs @@ -53,10 +53,6 @@ public static string Interpret(Atom.MathList mathList, System.Func entity.Alternate(5)); break; case MathItem.Set _: case MathItem.Comma _: diff --git a/Directory.Build.props b/Directory.Build.props index 165216a0..7a7556ce 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -37,6 +37,11 @@ true snupkg + + $(Configuration.Equals('Release')) + ``` -7. Replace `PACKAGE` in the above file by the package name in the webpage, e.g. `CSharpMath.SkiaSharp`, and `VERSION` by the version in the webpage, e.g. `0.4.2-ci-9db8a6dec29202804764fab9d6f7f19e43c3c083`. The 40-digit hexadecimal number at the end of the version is the Git commit that was the package was built on. CI versions for a version are newer than that version, aka chronologically `0.4.1-ci-xxx` → `0.4.2` → `0.4.2-ci-xxx`. +7. Replace `PACKAGE` in the above file by the package name in the webpage, e.g. `CSharpMath.SkiaSharp`, and `VERSION` by the version in the webpage, e.g. `0.4.2-ci-9db8a6dec29202804764fab9d6f7f19e43c3c083`. The 40-digit hexadecimal number at the end of the version is the Git commit that was the package was built on. CI versions for a version are older than that version, aka chronologically `0.4.2-ci-xxx` → `0.4.2` → `0.4.3-ci-xxx` → `0.5.0` → `0.5.1-ci-xxx`. ### SourceLink for CI packages Unfortunately, non-NuGet.org feeds do not support `.snupkg`s, so you will have to download all the packages yourself. From 5e2aa62aa64c81958046ec42f025abccd743eacc Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 20:12:54 +0800 Subject: [PATCH 02/20] Fix build --- Directory.Build.props | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 7a7556ce..31169e5c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -39,7 +39,8 @@ + It should not be enabled during local dev or the debugger won't be able to find the local source files. + Also, this requires SourceLink to be enabled or else error: https://github.com/dotnet/sourcelink/issues/91#issuecomment-400787926--> $(Configuration.Equals('Release')) @@ -52,10 +53,7 @@ $(MSBuildProjectName) $(MSBuildProjectName) - + From bb3479fcf689d2ccbf16a9b737aaf3cccd5ee8d3 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 20:22:31 +0800 Subject: [PATCH 03/20] Fix build 2 --- Directory.Build.props | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 31169e5c..c31210a5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -37,23 +37,25 @@ true snupkg - - $(Configuration.Equals('Release')) - $(Configuration.Equals('Release')) + + + $(GeneratePackageOnBuild) + $(MSBuildThisFileDirectory).nupkgs en $(MSBuildProjectName) $(MSBuildProjectName) - + From ae822048f4bdf6c9f628a53bac3cf04f231f2ee9 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 20:27:15 +0800 Subject: [PATCH 04/20] Simplify stuff --- Directory.Build.props | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index c31210a5..bd021cc6 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -38,10 +38,12 @@ snupkg + false $(Configuration.Equals('Release')) + And !$(MSBuildProjectName.Contains('Playground')) + And $(Configuration.Equals('Release'))">true $(MSBuildProjectName) - + From 88d9d8c658ca9c96e2c023c7ca9e2c20a3a06ffc Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 20:41:20 +0800 Subject: [PATCH 05/20] Make Extensions.cs the top-level source file of CSharpMath --- CSharpMath/Extensions.cs | 144 ++++++++++++++++++ CSharpMath/Extensions/IConvertible.cs | 9 -- CSharpMath/Extensions/IEnumerable.cs | 55 ------- .../Extensions/IEnumerable[IDisplay].cs | 20 --- CSharpMath/Extensions/IFormattable.cs | 9 -- CSharpMath/Extensions/PointF.cs | 8 - CSharpMath/Extensions/ReadOnlySpan.cs | 20 --- CSharpMath/Extensions/RectangleF.cs | 28 ---- CSharpMath/Extensions/Stack.cs | 10 -- CSharpMath/Extensions/StringBuilder.cs | 44 ------ 10 files changed, 144 insertions(+), 203 deletions(-) create mode 100644 CSharpMath/Extensions.cs delete mode 100644 CSharpMath/Extensions/IConvertible.cs delete mode 100644 CSharpMath/Extensions/IEnumerable.cs delete mode 100644 CSharpMath/Extensions/IEnumerable[IDisplay].cs delete mode 100644 CSharpMath/Extensions/IFormattable.cs delete mode 100644 CSharpMath/Extensions/PointF.cs delete mode 100644 CSharpMath/Extensions/ReadOnlySpan.cs delete mode 100644 CSharpMath/Extensions/RectangleF.cs delete mode 100644 CSharpMath/Extensions/Stack.cs delete mode 100644 CSharpMath/Extensions/StringBuilder.cs diff --git a/CSharpMath/Extensions.cs b/CSharpMath/Extensions.cs new file mode 100644 index 00000000..fdb57f39 --- /dev/null +++ b/CSharpMath/Extensions.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace CSharpMath { + using Display; + using Display.FrontEnd; + public static partial class Extensions { + public static string ToStringInvariant(this T value) where T : IConvertible => + value.ToString(CultureInfo.InvariantCulture); + public static string ToStringInvariant(this T value, string? format = null) + where T : IFormattable => value.ToString(format, CultureInfo.InvariantCulture); + public static bool IsEmpty(this IEnumerable enumerable) { + foreach (var _ in enumerable) return false; + return true; + } + public static bool IsNonEmpty(this IEnumerable enumerable) => !enumerable.IsEmpty(); + public static IEnumerable Zip( + this IEnumerable first, IEnumerable second, IEnumerable third, + Func resultSelector) { + return ZipIterator(); + IEnumerable ZipIterator() { + using var enum1 = first.GetEnumerator(); + using var enum2 = second.GetEnumerator(); + using var enum3 = third.GetEnumerator(); + while (enum1.MoveNext() && enum2.MoveNext() && enum3.MoveNext()) { + yield return resultSelector( + enum1.Current, + enum2.Current, + enum3.Current); + } + } + } + public static bool SequenceEqual(this IEnumerable enumerable, + IEnumerable otherEnumerable, Func? equalityTester = null) { + if (equalityTester == null) equalityTester = EqualityComparer.Default.Equals; + bool r; + if (enumerable == null && otherEnumerable == null) { + r = true; + } else if (enumerable != null && otherEnumerable != null) { + if (r = enumerable.Count() == otherEnumerable.Count()) { + using var enum1 = enumerable.GetEnumerator(); + using var enum2 = otherEnumerable.GetEnumerator(); + while (r && enum1.MoveNext() && enum2.MoveNext()) { + r = equalityTester(enum1.Current, enum2.Current); + } + } + } else { + // one enumerable is null and the other isn't + r = false; + } + return r; + } + public static float CollectionAscent + (this IEnumerable> displays) where TFont : IFont => + displays.IsNonEmpty() ? displays.Max(display => display.Ascent + display.Position.Y) : 0; + public static float CollectionDescent + (this IEnumerable> displays) where TFont : IFont => + displays.IsNonEmpty() ? displays.Max(display => display.Descent - display.Position.Y) : 0; + public static float CollectionWidth + (this IEnumerable> displays) where TFont : IFont => + displays.IsNonEmpty() + ? displays.Max(d => d.Position.X + d.Width) - displays.Min(d => d.Position.X) + : 0; + public static PointF Plus(this PointF point1, PointF point2) => + new PointF(point1.X + point2.X, point1.Y + point2.Y); + public static bool Is(this ReadOnlySpan span, char c) => + span.Length == 1 && span[0] == c; + public static bool IsNot(this ReadOnlySpan span, char c) => + span.Length != 1 || span[0] != c; + public static bool Is(this ReadOnlySpan span, string s) => + span.SequenceEqual(s.AsSpan()); + public static bool IsNot(this ReadOnlySpan span, string s) => + span.SequenceEqual(s.AsSpan()); + public static bool StartsWithInvariant(this ReadOnlySpan str, string prefix) => + str.StartsWith(prefix.AsSpan(), StringComparison.OrdinalIgnoreCase); + public static ReadOnlySpan RemovePrefix(this ReadOnlySpan str, + string prefix, StringComparison compare = StringComparison.OrdinalIgnoreCase) => + str.StartsWith(prefix.AsSpan(), compare) ? str.Slice(prefix.Length) : str; + public static RectangleF Plus(this RectangleF rect, PointF vector) => + new RectangleF(rect.Location.Plus(vector), rect.Size); + public static RectangleF Union(this RectangleF rect1, RectangleF rect2) { + var x = Math.Min(rect1.X, rect2.X); + var y = Math.Min(rect1.Y, rect2.Y); + var maxX = Math.Max(rect1.Right, rect2.Right); + var maxY = Math.Max(rect1.Bottom, rect2.Bottom); + return new RectangleF(x, y, maxX - x, maxY - y); + } + /// Because we are NOT inverting our y axis, + /// the properties "Top" and "Bottom" have misleading names. + public static float YMin(this RectangleF rect) => rect.Top; + /// Because we are NOT inverting our y axis, + /// the properties "Top" and "Bottom" have misleading names. + public static float YMax(this RectangleF rect) => rect.Bottom; + public static void GetAscentDescentWidth(this RectangleF rect, + out float ascent, out float descent, out float width) { + ascent = rect.Bottom; + width = rect.Width; + descent = -rect.Y; + } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static T PeekOrDefault(this Stack stack) => stack.Count == 0 ? default : stack.Peek(); + public static StringBuilder Append(this StringBuilder sb, ReadOnlySpan value) { + sb.EnsureCapacity(sb.Length + value.Length); + for (int i = 0; i < value.Length; i++) sb.Append(value[i]); + return sb; + } + private enum NullHandling { + ///the string "null", without the quotes + LiteralNull, + /// Change the null to the empty string, then wrap. + EmptyContent, + /// Return the empty string. Do not wrap. + EmptyString, + } + private static StringBuilder AppendIn(this StringBuilder b, char l, string? s, char r, NullHandling h) => + h switch + { + NullHandling.EmptyContent => b.Append(l).Append(s).Append(r), + NullHandling.EmptyString => s != null ? b.Append(l).Append(s).Append(r) : b, + NullHandling.LiteralNull => b.Append(l).Append(s ?? "null").Append(r), + _ => + throw new System.ComponentModel.InvalidEnumArgumentException(nameof(h), (int)h, typeof(NullHandling)) + }; + internal static StringBuilder AppendInBracesOrLiteralNull(this StringBuilder builder, string? appendMe) => + builder.AppendIn('{', appendMe, '}', NullHandling.LiteralNull); + internal static StringBuilder AppendInBracesOrEmptyBraces(this StringBuilder builder, string? appendMe) => + builder.AppendIn('{', appendMe, '}', NullHandling.EmptyContent); + internal static StringBuilder AppendInBracketsOrNothing(this StringBuilder builder, string? appendMe) => + builder.AppendIn('[', appendMe, ']', NullHandling.EmptyString); + internal static StringBuilder AppendDebugStringOfScripts(this StringBuilder builder, Atom.MathAtom target) { + if (target.Subscript.IsNonEmpty()) { + builder.Append('_').AppendInBracesOrLiteralNull(target.Subscript.DebugString); + } + if (target.Superscript.IsNonEmpty()) { + builder.Append('^').AppendInBracesOrLiteralNull(target.Superscript.DebugString); + } + return builder; + } + } +} diff --git a/CSharpMath/Extensions/IConvertible.cs b/CSharpMath/Extensions/IConvertible.cs deleted file mode 100644 index 74cd727f..00000000 --- a/CSharpMath/Extensions/IConvertible.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using System.Globalization; - -namespace CSharpMath { - public static partial class Extensions { - public static string ToStringInvariant(this T value) where T : IConvertible => - value.ToString(CultureInfo.InvariantCulture); - } -} \ No newline at end of file diff --git a/CSharpMath/Extensions/IEnumerable.cs b/CSharpMath/Extensions/IEnumerable.cs deleted file mode 100644 index 8fb1126a..00000000 --- a/CSharpMath/Extensions/IEnumerable.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace CSharpMath { - public static partial class Extensions { - public static bool IsEmpty(this IEnumerable enumerable) { - if (enumerable == null) return true; - foreach (var _ in enumerable) return false; - return true; - } - public static bool IsNonEmpty(this IEnumerable enumerable) => !enumerable.IsEmpty(); - public static IEnumerable Zip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - Func resultSelector) { - if (first is null) throw new ArgumentNullException(nameof(first)); - if (second is null) throw new ArgumentNullException(nameof(second)); - if (third is null) throw new ArgumentNullException(nameof(third)); - return ZipIterator(); - IEnumerable ZipIterator() { - using var enum1 = first.GetEnumerator(); - using var enum2 = second.GetEnumerator(); - using var enum3 = third.GetEnumerator(); - while (enum1.MoveNext() && enum2.MoveNext() && enum3.MoveNext()) { - yield return resultSelector( - enum1.Current, - enum2.Current, - enum3.Current); - } - } - } - public static bool SequenceEqual(this IEnumerable enumerable, - IEnumerable otherEnumerable, Func? equalityTester = null) { - if (equalityTester == null) equalityTester = EqualityComparer.Default.Equals; - bool r; - if (enumerable == null && otherEnumerable == null) { - r = true; - } else if (enumerable != null && otherEnumerable != null) { - if (r = enumerable.Count() == otherEnumerable.Count()) { - using var enum1 = enumerable.GetEnumerator(); - using var enum2 = otherEnumerable.GetEnumerator(); - while (r && enum1.MoveNext() && enum2.MoveNext()) { - r = equalityTester(enum1.Current, enum2.Current); - } - } - } else { - // one enumerable is null and the other isn't - r = false; - } - return r; - } - } -} \ No newline at end of file diff --git a/CSharpMath/Extensions/IEnumerable[IDisplay].cs b/CSharpMath/Extensions/IEnumerable[IDisplay].cs deleted file mode 100644 index a21dcf0c..00000000 --- a/CSharpMath/Extensions/IEnumerable[IDisplay].cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace CSharpMath { - using Display; - using Display.FrontEnd; - public static partial class Extensions { - public static float CollectionAscent - (this IEnumerable> displays) where TFont : IFont => - displays.IsNonEmpty() ? displays.Max(display => display.Ascent + display.Position.Y) : 0; - public static float CollectionDescent - (this IEnumerable> displays) where TFont : IFont => - displays.IsNonEmpty() ? displays.Max(display => display.Descent - display.Position.Y) : 0; - public static float CollectionWidth - (this IEnumerable> displays) where TFont : IFont => - displays.IsNonEmpty() - ? displays.Max(d => d.Position.X + d.Width) - displays.Min(d => d.Position.X) - : 0; - } -} diff --git a/CSharpMath/Extensions/IFormattable.cs b/CSharpMath/Extensions/IFormattable.cs deleted file mode 100644 index e21edc81..00000000 --- a/CSharpMath/Extensions/IFormattable.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using System.Globalization; - -namespace CSharpMath { - public static partial class Extensions { - public static string ToStringInvariant(this T value, string? format = null) - where T : IFormattable => value.ToString(format, CultureInfo.InvariantCulture); - } -} \ No newline at end of file diff --git a/CSharpMath/Extensions/PointF.cs b/CSharpMath/Extensions/PointF.cs deleted file mode 100644 index b6b0fb1a..00000000 --- a/CSharpMath/Extensions/PointF.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Drawing; - -namespace CSharpMath { - public static partial class Extensions { - public static PointF Plus(this PointF point1, PointF point2) => - new PointF(point1.X + point2.X, point1.Y + point2.Y); - } -} \ No newline at end of file diff --git a/CSharpMath/Extensions/ReadOnlySpan.cs b/CSharpMath/Extensions/ReadOnlySpan.cs deleted file mode 100644 index 61b3137e..00000000 --- a/CSharpMath/Extensions/ReadOnlySpan.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Linq; - -namespace CSharpMath { - public static partial class Extensions { - public static bool Is(this ReadOnlySpan span, char c) => - span.Length == 1 && span[0] == c; - public static bool IsNot(this ReadOnlySpan span, char c) => - span.Length != 1 || span[0] != c; - public static bool Is(this ReadOnlySpan span, string s) => - span.SequenceEqual(s.AsSpan()); - public static bool IsNot(this ReadOnlySpan span, string s) => - span.SequenceEqual(s.AsSpan()); - public static bool StartsWithInvariant(this ReadOnlySpan str, string prefix) => - str.StartsWith(prefix.AsSpan(), StringComparison.OrdinalIgnoreCase); - public static ReadOnlySpan RemovePrefix(this ReadOnlySpan str, - string prefix, StringComparison compare = StringComparison.OrdinalIgnoreCase) => - str.StartsWith(prefix.AsSpan(), compare) ? str.Slice(prefix.Length) : str; - } -} diff --git a/CSharpMath/Extensions/RectangleF.cs b/CSharpMath/Extensions/RectangleF.cs deleted file mode 100644 index 0b3a3081..00000000 --- a/CSharpMath/Extensions/RectangleF.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Drawing; - -namespace CSharpMath { - public static partial class Extensions { - public static RectangleF Plus(this RectangleF rect, PointF vector) => - new RectangleF(rect.Location.Plus(vector), rect.Size); - public static RectangleF Union(this RectangleF rect1, RectangleF rect2) { - var x = Math.Min(rect1.X, rect2.X); - var y = Math.Min(rect1.Y, rect2.Y); - var maxX = Math.Max(rect1.Right, rect2.Right); - var maxY = Math.Max(rect1.Bottom, rect2.Bottom); - return new RectangleF(x, y, maxX - x, maxY - y); - } - /// Because we are NOT inverting our y axis, - /// the properties "Top" and "Bottom" have misleading names. - public static float YMin(this RectangleF rect) => rect.Top; - /// Because we are NOT inverting our y axis, - /// the properties "Top" and "Bottom" have misleading names. - public static float YMax(this RectangleF rect) => rect.Bottom; - public static void GetAscentDescentWidth(this RectangleF rect, - out float ascent, out float descent, out float width) { - ascent = rect.Bottom; - width = rect.Width; - descent = -rect.Y; - } - } -} diff --git a/CSharpMath/Extensions/Stack.cs b/CSharpMath/Extensions/Stack.cs deleted file mode 100644 index 544f3428..00000000 --- a/CSharpMath/Extensions/Stack.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace CSharpMath { - partial class Extensions { - [return: System.Diagnostics.CodeAnalysis.MaybeNull] - public static T PeekOrDefault(this Stack stack) => stack.Count == 0 ? default : stack.Peek(); - } -} diff --git a/CSharpMath/Extensions/StringBuilder.cs b/CSharpMath/Extensions/StringBuilder.cs deleted file mode 100644 index 8d107e3f..00000000 --- a/CSharpMath/Extensions/StringBuilder.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Text; - -namespace CSharpMath { - public static partial class Extensions { - public static StringBuilder Append(this StringBuilder sb, ReadOnlySpan value) { - sb.EnsureCapacity(sb.Length + value.Length); - for (int i = 0; i < value.Length; i++) sb.Append(value[i]); - return sb; - } - private enum NullHandling { - ///the string "null", without the quotes - LiteralNull, - /// Change the null to the empty string, then wrap. - EmptyContent, - /// Return the empty string. Do not wrap. - EmptyString, - } - private static StringBuilder AppendIn(this StringBuilder b, char l, string? s, char r, NullHandling h) => - h switch - { - NullHandling.EmptyContent => b.Append(l).Append(s).Append(r), - NullHandling.EmptyString => s != null ? b.Append(l).Append(s).Append(r) : b, - NullHandling.LiteralNull => b.Append(l).Append(s ?? "null").Append(r), - _ => - throw new System.ComponentModel.InvalidEnumArgumentException(nameof(h), (int)h, typeof(NullHandling)) - }; - internal static StringBuilder AppendInBracesOrLiteralNull(this StringBuilder builder, string? appendMe) => - builder.AppendIn('{', appendMe, '}', NullHandling.LiteralNull); - internal static StringBuilder AppendInBracesOrEmptyBraces(this StringBuilder builder, string? appendMe) => - builder.AppendIn('{', appendMe, '}', NullHandling.EmptyContent); - internal static StringBuilder AppendInBracketsOrNothing(this StringBuilder builder, string? appendMe) => - builder.AppendIn('[', appendMe, ']', NullHandling.EmptyString); - internal static StringBuilder AppendDebugStringOfScripts(this StringBuilder builder, Atom.MathAtom target) { - if (target.Subscript.IsNonEmpty()) { - builder.Append('_').AppendInBracesOrLiteralNull(target.Subscript.DebugString); - } - if (target.Superscript.IsNonEmpty()) { - builder.Append('^').AppendInBracesOrLiteralNull(target.Superscript.DebugString); - } - return builder; - } - } -} \ No newline at end of file From bb88df6e3f3ade5dc259d248a297db100021b453 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 20:50:08 +0800 Subject: [PATCH 06/20] ?? Windows? --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index bd021cc6..e8704526 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -75,4 +75,4 @@ - + \ No newline at end of file From 613cccf43f8492e0bada1080bd752046c5d0ef4e Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 20:51:18 +0800 Subject: [PATCH 07/20] Update Build.yml --- .github/workflows/Build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Build.yml b/.github/workflows/Build.yml index 42948d45..6f777ccb 100644 --- a/.github/workflows/Build.yml +++ b/.github/workflows/Build.yml @@ -18,5 +18,5 @@ jobs: uses: warrenbuckley/Setup-MSBuild@v1 - name: Restore NuGet Packages run: nuget restore CSharpMath.sln - - name: Build CI artifacts + - name: Build everything run: msbuild CSharpMath.sln /p:Configuration=Release From 4504e1e96e3088897867684bbf6d95581c79346d Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 20:51:31 +0800 Subject: [PATCH 08/20] E --- .github/workflows/Build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Build.yml b/.github/workflows/Build.yml index 6f777ccb..080e6f6b 100644 --- a/.github/workflows/Build.yml +++ b/.github/workflows/Build.yml @@ -18,5 +18,5 @@ jobs: uses: warrenbuckley/Setup-MSBuild@v1 - name: Restore NuGet Packages run: nuget restore CSharpMath.sln - - name: Build everything + - name: Build Everything run: msbuild CSharpMath.sln /p:Configuration=Release From df832befdb3a21700dc51708ae4558552691612b Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 21:00:09 +0800 Subject: [PATCH 09/20] Update Build.yml --- .github/workflows/Build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Build.yml b/.github/workflows/Build.yml index 080e6f6b..3263d6af 100644 --- a/.github/workflows/Build.yml +++ b/.github/workflows/Build.yml @@ -19,4 +19,4 @@ jobs: - name: Restore NuGet Packages run: nuget restore CSharpMath.sln - name: Build Everything - run: msbuild CSharpMath.sln /p:Configuration=Release + run: msbuild CSharpMath.sln /p:Configuration=Debug From cf83768a6b5acaf7288b12b06ff663f5442c9eb9 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 22:57:43 +0800 Subject: [PATCH 10/20] Try fix? --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index e8704526..26013fad 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -56,7 +56,7 @@ $(MSBuildProjectName) $(MSBuildProjectName) - + From 1b244b8eb482ef430e090907447951e2e8c595f4 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 23:02:48 +0800 Subject: [PATCH 11/20] Update Build.yml --- .github/workflows/Build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Build.yml b/.github/workflows/Build.yml index 3263d6af..080e6f6b 100644 --- a/.github/workflows/Build.yml +++ b/.github/workflows/Build.yml @@ -19,4 +19,4 @@ jobs: - name: Restore NuGet Packages run: nuget restore CSharpMath.sln - name: Build Everything - run: msbuild CSharpMath.sln /p:Configuration=Debug + run: msbuild CSharpMath.sln /p:Configuration=Release From 71b8551af49b462ac09907f3981ebcae4bd0ee40 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 23:30:29 +0800 Subject: [PATCH 12/20] Detect dotnet msbuild --- Directory.Build.props | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 26013fad..ef9385b5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -49,7 +49,8 @@ Deterministic builds are important as they enable verification that the resulting binary was built from the specified source and provides traceability. It should not be enabled during local dev or the debugger won't be able to find the local source files. Also, this requires SourceLink to be enabled or else error: https://github.com/dotnet/sourcelink/issues/91#issuecomment-400787926--> - $(GeneratePackageOnBuild) + + $(GeneratePackageOnBuild) $(MSBuildThisFileDirectory).nupkgs en From 0b876700bac75e3f797d6ab1f14cc0dc8601fe6d Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 23:44:46 +0800 Subject: [PATCH 13/20] Update Directory.Build.props --- Directory.Build.props | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index ef9385b5..b0d1c689 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -57,7 +57,8 @@ $(MSBuildProjectName) $(MSBuildProjectName) - + + @@ -76,4 +77,4 @@ - \ No newline at end of file + From 4471ee8ec24d0f2c4fee4b163a1e205291d97dbf Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 23:50:39 +0800 Subject: [PATCH 14/20] Update Test.yml --- .github/workflows/Test.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/Test.yml b/.github/workflows/Test.yml index 23e721a1..9b316e37 100644 --- a/.github/workflows/Test.yml +++ b/.github/workflows/Test.yml @@ -5,6 +5,11 @@ jobs: Core: runs-on: ubuntu-latest # release-drafter/release-drafter@v5 only works on Linux: https://github.com/release-drafter/release-drafter/issues/558 steps: + - name: Sleep for 30 seconds + if: github.event_name == 'push' # Avoid Release Drafter running in parallel and failing to update the draft release + uses: jakejarvis/wait-action@master + with: + time: '30s' - name: Update draft on GitHub Releases id: release_drafter uses: release-drafter/release-drafter@v5 From b3feede0d398b265149ff8f84116299ebafa0128 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sat, 1 Aug 2020 23:57:40 +0800 Subject: [PATCH 15/20] Update Test.yml --- .github/workflows/Test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Test.yml b/.github/workflows/Test.yml index 9b316e37..b1fc311a 100644 --- a/.github/workflows/Test.yml +++ b/.github/workflows/Test.yml @@ -6,7 +6,7 @@ jobs: runs-on: ubuntu-latest # release-drafter/release-drafter@v5 only works on Linux: https://github.com/release-drafter/release-drafter/issues/558 steps: - name: Sleep for 30 seconds - if: github.event_name == 'push' # Avoid Release Drafter running in parallel and failing to update the draft release + if: github.event_name == 'pull_request' # Avoid Release Drafter running in parallel and failing to update the draft release uses: jakejarvis/wait-action@master with: time: '30s' From 3b7df6fad8707573c71d33a8db6ac09d0431ee8f Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 2 Aug 2020 00:22:44 +0800 Subject: [PATCH 16/20] Sleeping does nothing --- .github/workflows/Test.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/Test.yml b/.github/workflows/Test.yml index b1fc311a..23e721a1 100644 --- a/.github/workflows/Test.yml +++ b/.github/workflows/Test.yml @@ -5,11 +5,6 @@ jobs: Core: runs-on: ubuntu-latest # release-drafter/release-drafter@v5 only works on Linux: https://github.com/release-drafter/release-drafter/issues/558 steps: - - name: Sleep for 30 seconds - if: github.event_name == 'pull_request' # Avoid Release Drafter running in parallel and failing to update the draft release - uses: jakejarvis/wait-action@master - with: - time: '30s' - name: Update draft on GitHub Releases id: release_drafter uses: release-drafter/release-drafter@v5 From d25a10d5e36899633765669d415382b6858ad396 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 2 Aug 2020 13:15:44 +0800 Subject: [PATCH 17/20] Simplify --- .github/workflows/Test.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/Test.yml b/.github/workflows/Test.yml index 23e721a1..fbe847a6 100644 --- a/.github/workflows/Test.yml +++ b/.github/workflows/Test.yml @@ -10,12 +10,6 @@ jobs: uses: release-drafter/release-drafter@v5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: cardinalby/git-get-release-action@v1 - id: release_info - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - releaseId: ${{ steps.release_drafter.outputs.id }} - uses: actions/checkout@v2 with: submodules: 'recursive' @@ -35,9 +29,9 @@ jobs: - name: Build and Test env: RELEASE_NOTES: | - # ${{ steps.release_info.outputs.name }} + # ${{ steps.release_drafter.outputs.name }} - ${{ steps.release_info.outputs.body }} + ${{ steps.release_drafter.outputs.body }} # run: dotnet test CSharpMath.CrossPlatform.slnf run: | # https://github.com/dotnet/sdk/issues/10409, https://github.com/dotnet/sdk/issues/11417 # .NET Core MSBuild cannot parse , and ; correctly so we replace them with substitutions: https://github.com/dotnet/msbuild/issues/471#issuecomment-366268743 From 1068e273c4ac7b3e29addf6c94e0d3e1bea629d9 Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 2 Aug 2020 13:18:33 +0800 Subject: [PATCH 18/20] Update Test.yml --- .github/workflows/Test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Test.yml b/.github/workflows/Test.yml index fbe847a6..e51c535a 100644 --- a/.github/workflows/Test.yml +++ b/.github/workflows/Test.yml @@ -54,7 +54,7 @@ jobs: dotnet add "$p" package Microsoft.NET.Test.Sdk # Update is required for GitHubActionsTestLogger to print anything dotnet add "$p" package GitHubActionsTestLogger # -r for restore - dotnet msbuild -r -p:Configuration=Release -p:PackageVersion=${{ steps.release_drafter.outputs.tag_name }}-ci-${{ github.sha }} -p:PackageReleaseNotes="$RELEASE_NOTES" "$p" + dotnet msbuild -r -p:Configuration=Release -p:PackageVersion=${{ steps.release_drafter.outputs.tag_name || format('{0}-pr', github.event.number) }}-ci-${{ github.sha }} -p:PackageReleaseNotes="$RELEASE_NOTES" "$p" # --no-build because building again will produce additional NuGet packages without the PackageVersion setting above dotnet test "$p" --no-build -c Release -l GitHubActions --blame done From b14c696b0f389714817a0b6d12fb4faf9140891f Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 2 Aug 2020 15:16:18 +0800 Subject: [PATCH 19/20] Update local build version --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index ef9385b5..093d6263 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -68,7 +68,7 @@ - + From f6096a036e6fd5b1db81bdf584bcef6bb293786f Mon Sep 17 00:00:00 2001 From: Hadrian Tang Date: Sun, 2 Aug 2020 15:27:16 +0800 Subject: [PATCH 20/20] Update Test.yml --- .github/workflows/Test.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Test.yml b/.github/workflows/Test.yml index e51c535a..cd316108 100644 --- a/.github/workflows/Test.yml +++ b/.github/workflows/Test.yml @@ -58,12 +58,13 @@ jobs: # --no-build because building again will produce additional NuGet packages without the PackageVersion setting above dotnet test "$p" --no-build -c Release -l GitHubActions --blame done - - uses: actions/upload-artifact@v2 + - name: Upload CSharpMath.Rendering.Tests results as CI artifacts + uses: actions/upload-artifact@v2 if: always() # Run even when a previous step failed: https://stackoverflow.com/a/58859404/5429648 with: name: CSharpMath.Rendering.Tests results path: CSharpMath.Rendering.Tests/*/*.png - - name: Upload CI artifacts + - name: Upload NuGet packages as CI artifacts uses: actions/upload-artifact@v2 if: always() with: