From 2ef0efcceb897a31535b84ded874113124508aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edu=20Gonz=C3=A1lez=20de=20la=20Herr=C3=A1n?= <25320357+eedugon@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:32:40 +0100 Subject: [PATCH 1/3] initial attempt --- docs/syntax/substitutions.md | 3 ++ docs/syntax/version-variables.md | 1 + .../SubstitutionMutationHelper.cs | 1 + .../Substitution/SubstitutionParser.cs | 1 + .../Inline/SubstitutionTest.cs | 36 ++++++++++++++++++- .../authoring/Inline/SubstitutionMutations.fs | 2 ++ 6 files changed, 43 insertions(+), 1 deletion(-) diff --git a/docs/syntax/substitutions.md b/docs/syntax/substitutions.md index 331cfd44a..43a8ea351 100644 --- a/docs/syntax/substitutions.md +++ b/docs/syntax/substitutions.md @@ -78,6 +78,7 @@ For variables declaring a semantic version or `Major.Minor` the following operat | `M.M` | Display only the major and the minor | | `M+1` | The next major version | | `M.M+1` | The next minor version | +| `M.M-1` | The previous minor version (returns original value if minor is 0) | ### Example @@ -109,6 +110,7 @@ sub: * M+1: {{version.stack | M+1 }} * M+1 | M.M: {{version.stack | M+1 | M.M }} * M.M+1: {{version.stack | M.M+1 }} +* M.M-1: {{version.stack | M.M-1 }} ::: @@ -130,6 +132,7 @@ sub: * M+1: {{version.stack | M+1 }} * M+1 | M.M: {{version.stack | M+1 | M.M }} * M.M+1: {{version.stack | M.M+1 }} +* M.M-1: {{version.stack | M.M-1 }} ```` ::: diff --git a/docs/syntax/version-variables.md b/docs/syntax/version-variables.md index f841d63a6..0285f4a83 100644 --- a/docs/syntax/version-variables.md +++ b/docs/syntax/version-variables.md @@ -25,6 +25,7 @@ can be printed in any kind of ways. | `{{version.stack.base | M }}` | {{version.stack.base | M }} | | `{{version.stack | M+1 | M }}` | {{version.stack | M+1 | M }} | | `{{version.stack.base | M.M+1 }}` | {{version.stack.base | M.M+1 }} | +| `{{version.stack | M.M-1 }}` | {{version.stack | M.M-1 }} | ## Mutation Operators in Links and Code Blocks diff --git a/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionMutationHelper.cs b/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionMutationHelper.cs index f5e696a9c..9bb69fe97 100644 --- a/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionMutationHelper.cs +++ b/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionMutationHelper.cs @@ -74,6 +74,7 @@ private static string ApplySingleMutation(string value, SubstitutionMutation mut SubstitutionMutation.MajorMinor => TryGetVersion(value, v => $"{v.Major}.{v.Minor}"), SubstitutionMutation.IncreaseMajor => TryGetVersion(value, v => $"{v.Major + 1}.0.0"), SubstitutionMutation.IncreaseMinor => TryGetVersion(value, v => $"{v.Major}.{v.Minor + 1}.0"), + SubstitutionMutation.DecreaseMinor => TryGetVersion(value, v => v.Minor == 0 ? value : $"{v.Major}.{v.Minor - 1}.0"), SubstitutionMutation.LowerCase => (true, value.ToLowerInvariant()), SubstitutionMutation.UpperCase => (true, value.ToUpperInvariant()), SubstitutionMutation.Capitalize => (true, Capitalize(value)), diff --git a/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionParser.cs b/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionParser.cs index 78c29dc8f..4f59fe8fb 100644 --- a/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionParser.cs +++ b/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionParser.cs @@ -34,6 +34,7 @@ public enum SubstitutionMutation [Display(Name = "M.M")] MajorMinor, [Display(Name = "M+1")] IncreaseMajor, [Display(Name = "M.M+1")] IncreaseMinor, + [Display(Name = "M.M-1")] DecreaseMinor, [Display(Name = "lc")] LowerCase, [Display(Name = "uc")] UpperCase, [Display(Name = "tc")] TitleCase, diff --git a/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs b/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs index 079970d6b..d5ae1ba26 100644 --- a/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs +++ b/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs @@ -225,6 +225,8 @@ public class MutationOperatorTest(ITestOutputHelper output) : InlineTest(output, Increase major with space: {{version | M+1}} Increase minor: {{version|M.M+1}} Increase minor with space: {{version | M.M+1}} +Decrease minor: {{version|M.M-1}} +Decrease minor with space: {{version | M.M-1}} """ ) { @@ -241,7 +243,39 @@ public void MutationOperatorsWorkWithAndWithoutSpaces() .And.Contain("Increase major: 10.0.0") .And.Contain("Increase major with space: 10.0.0") .And.Contain("Increase minor: 9.1.0") - .And.Contain("Increase minor with space: 9.1.0"); + .And.Contain("Increase minor with space: 9.1.0") + .And.Contain("Decrease minor: 9.0.4") + .And.Contain("Decrease minor with space: 9.0.4"); + } + + [Fact] + public void HasNoErrors() => Collector.Diagnostics.Should().HaveCount(0); +} + +public class DecreaseMinorMutationTest(ITestOutputHelper output) : InlineTest(output, +""" +--- +sub: + version-with-minor: "9.2.3" + version-with-zero-minor: "9.0.4" +--- + +# Testing Decrease Minor Mutation + +Version with minor > 0: {{version-with-minor|M.M-1}} +Version with minor > 0 and M.M: {{version-with-minor|M.M-1|M.M}} +Version with minor = 0: {{version-with-zero-minor|M.M-1}} +""" +) +{ + [Fact] + public void DecreaseMinorWorksCorrectly() + { + // When minor > 0, should decrease minor + Html.Should().Contain("Version with minor > 0: 9.1.0") + .And.Contain("Version with minor > 0 and M.M: 9.1") + // When minor = 0, should return original value + .And.Contain("Version with minor = 0: 9.0.4"); } [Fact] diff --git a/tests/authoring/Inline/SubstitutionMutations.fs b/tests/authoring/Inline/SubstitutionMutations.fs index 50600f0ee..5bbc5f263 100644 --- a/tests/authoring/Inline/SubstitutionMutations.fs +++ b/tests/authoring/Inline/SubstitutionMutations.fs @@ -28,6 +28,7 @@ sub: * M+1: {{versions.stack | M+1 }} * M+1 | M.M: {{versions.stack | M+1 | M.M }} * M.M+1: {{versions.stack | M.M+1 }} +* M.M-1: {{versions.stack | M.M-1 }} """ [] @@ -48,5 +49,6 @@ sub:
  • M+1: 10.0.0
  • M+1 | M.M: 10.0
  • M.M+1: 9.2.0
  • +
  • M.M-1: 9.0.0
  • """ From 28a3a20a2cd38fe7c01426fab0ca629b63c37fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edu=20Gonz=C3=A1lez=20de=20la=20Herr=C3=A1n?= <25320357+eedugon@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:52:49 +0100 Subject: [PATCH 2/3] unit test updated --- .../Inline/SubstitutionTest.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs b/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs index d5ae1ba26..3415c1992 100644 --- a/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs +++ b/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs @@ -262,9 +262,9 @@ public class DecreaseMinorMutationTest(ITestOutputHelper output) : InlineTest(ou # Testing Decrease Minor Mutation -Version with minor > 0: {{version-with-minor|M.M-1}} -Version with minor > 0 and M.M: {{version-with-minor|M.M-1|M.M}} -Version with minor = 0: {{version-with-zero-minor|M.M-1}} +Version with minor greater than 0: {{version-with-minor|M.M-1}} +Version with minor greater than 0 and M.M: {{version-with-minor|M.M-1|M.M}} +Version with minor 0: {{version-with-zero-minor|M.M-1}} """ ) { @@ -272,10 +272,10 @@ public class DecreaseMinorMutationTest(ITestOutputHelper output) : InlineTest(ou public void DecreaseMinorWorksCorrectly() { // When minor > 0, should decrease minor - Html.Should().Contain("Version with minor > 0: 9.1.0") - .And.Contain("Version with minor > 0 and M.M: 9.1") + Html.Should().Contain("Version with minor greater than 0: 9.1.0") + .And.Contain("Version with minor greater than 0 and M.M: 9.1") // When minor = 0, should return original value - .And.Contain("Version with minor = 0: 9.0.4"); + .And.Contain("Version with minor 0: 9.0.4"); } [Fact] From a1044319de2cfaffe50e8f4be19e19efbf9f74bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edu=20Gonz=C3=A1lez=20de=20la=20Herr=C3=A1n?= <25320357+eedugon@users.noreply.github.com> Date: Wed, 14 Jan 2026 10:43:11 +0100 Subject: [PATCH 3/3] decrease major implemented --- docs/syntax/substitutions.md | 3 ++ docs/syntax/version-variables.md | 1 + .../SubstitutionMutationHelper.cs | 1 + .../Substitution/SubstitutionParser.cs | 1 + .../Inline/SubstitutionTest.cs | 34 +++++++++++++++++++ .../authoring/Inline/SubstitutionMutations.fs | 2 ++ 6 files changed, 42 insertions(+) diff --git a/docs/syntax/substitutions.md b/docs/syntax/substitutions.md index 43a8ea351..89200e910 100644 --- a/docs/syntax/substitutions.md +++ b/docs/syntax/substitutions.md @@ -77,6 +77,7 @@ For variables declaring a semantic version or `Major.Minor` the following operat | `M.x` | Display major component followed by '.x' | | `M.M` | Display only the major and the minor | | `M+1` | The next major version | +| `M-1` | The previous major version (returns original value if major is 0) | | `M.M+1` | The next minor version | | `M.M-1` | The previous minor version (returns original value if minor is 0) | @@ -108,6 +109,7 @@ sub: * M.M: {{version.stack | M.M }} * M: {{version.stack | M }} * M+1: {{version.stack | M+1 }} +* M-1: {{version.stack | M-1 }} * M+1 | M.M: {{version.stack | M+1 | M.M }} * M.M+1: {{version.stack | M.M+1 }} * M.M-1: {{version.stack | M.M-1 }} @@ -130,6 +132,7 @@ sub: * M.M: {{version.stack | M.M }} * M: {{version.stack | M }} * M+1: {{version.stack | M+1 }} +* M-1: {{version.stack | M-1 }} * M+1 | M.M: {{version.stack | M+1 | M.M }} * M.M+1: {{version.stack | M.M+1 }} * M.M-1: {{version.stack | M.M-1 }} diff --git a/docs/syntax/version-variables.md b/docs/syntax/version-variables.md index 0285f4a83..9365029d9 100644 --- a/docs/syntax/version-variables.md +++ b/docs/syntax/version-variables.md @@ -24,6 +24,7 @@ can be printed in any kind of ways. | `{{version.stack| M.M}}` | {{version.stack|M.M}} | | `{{version.stack.base | M }}` | {{version.stack.base | M }} | | `{{version.stack | M+1 | M }}` | {{version.stack | M+1 | M }} | +| `{{version.stack | M-1 }}` | {{version.stack | M-1 }} | | `{{version.stack.base | M.M+1 }}` | {{version.stack.base | M.M+1 }} | | `{{version.stack | M.M-1 }}` | {{version.stack | M.M-1 }} | diff --git a/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionMutationHelper.cs b/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionMutationHelper.cs index 9bb69fe97..0edc56818 100644 --- a/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionMutationHelper.cs +++ b/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionMutationHelper.cs @@ -73,6 +73,7 @@ private static string ApplySingleMutation(string value, SubstitutionMutation mut SubstitutionMutation.MajorX => TryGetVersion(value, v => $"{v.Major}.x"), SubstitutionMutation.MajorMinor => TryGetVersion(value, v => $"{v.Major}.{v.Minor}"), SubstitutionMutation.IncreaseMajor => TryGetVersion(value, v => $"{v.Major + 1}.0.0"), + SubstitutionMutation.DecreaseMajor => TryGetVersion(value, v => v.Major == 0 ? value : $"{v.Major - 1}.0.0"), SubstitutionMutation.IncreaseMinor => TryGetVersion(value, v => $"{v.Major}.{v.Minor + 1}.0"), SubstitutionMutation.DecreaseMinor => TryGetVersion(value, v => v.Minor == 0 ? value : $"{v.Major}.{v.Minor - 1}.0"), SubstitutionMutation.LowerCase => (true, value.ToLowerInvariant()), diff --git a/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionParser.cs b/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionParser.cs index 4f59fe8fb..81e9a8e1f 100644 --- a/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionParser.cs +++ b/src/Elastic.Markdown/Myst/InlineParsers/Substitution/SubstitutionParser.cs @@ -33,6 +33,7 @@ public enum SubstitutionMutation [Display(Name = "M.x")] MajorX, [Display(Name = "M.M")] MajorMinor, [Display(Name = "M+1")] IncreaseMajor, + [Display(Name = "M-1")] DecreaseMajor, [Display(Name = "M.M+1")] IncreaseMinor, [Display(Name = "M.M-1")] DecreaseMinor, [Display(Name = "lc")] LowerCase, diff --git a/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs b/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs index 3415c1992..c6b5d762a 100644 --- a/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs +++ b/tests/Elastic.Markdown.Tests/Inline/SubstitutionTest.cs @@ -223,6 +223,8 @@ public class MutationOperatorTest(ITestOutputHelper output) : InlineTest(output, Major.x with space: {{version | M.x}} Increase major: {{version|M+1}} Increase major with space: {{version | M+1}} +Decrease major: {{version|M-1}} +Decrease major with space: {{version | M-1}} Increase minor: {{version|M.M+1}} Increase minor with space: {{version | M.M+1}} Decrease minor: {{version|M.M-1}} @@ -242,6 +244,8 @@ public void MutationOperatorsWorkWithAndWithoutSpaces() .And.Contain("Major.x with space: 9.x") .And.Contain("Increase major: 10.0.0") .And.Contain("Increase major with space: 10.0.0") + .And.Contain("Decrease major: 8.0.0") + .And.Contain("Decrease major with space: 8.0.0") .And.Contain("Increase minor: 9.1.0") .And.Contain("Increase minor with space: 9.1.0") .And.Contain("Decrease minor: 9.0.4") @@ -282,6 +286,36 @@ public void DecreaseMinorWorksCorrectly() public void HasNoErrors() => Collector.Diagnostics.Should().HaveCount(0); } +public class DecreaseMajorMutationTest(ITestOutputHelper output) : InlineTest(output, +""" +--- +sub: + version-with-major: "9.2.3" + version-with-zero-major: "0.5.2" +--- + +# Testing Decrease Major Mutation + +Version with major greater than 0: {{version-with-major|M-1}} +Version with major greater than 0 and M.M: {{version-with-major|M-1|M.M}} +Version with major 0: {{version-with-zero-major|M-1}} +""" +) +{ + [Fact] + public void DecreaseMajorWorksCorrectly() + { + // When major > 0, should decrease major and set minor/patch to 0 + Html.Should().Contain("Version with major greater than 0: 8.0.0") + .And.Contain("Version with major greater than 0 and M.M: 8.0") + // When major = 0, should return original value + .And.Contain("Version with major 0: 0.5.2"); + } + + [Fact] + public void HasNoErrors() => Collector.Diagnostics.Should().HaveCount(0); +} + public class MultipleMutationOperatorsTest(ITestOutputHelper output) : InlineTest(output, """ --- diff --git a/tests/authoring/Inline/SubstitutionMutations.fs b/tests/authoring/Inline/SubstitutionMutations.fs index 5bbc5f263..067f8a005 100644 --- a/tests/authoring/Inline/SubstitutionMutations.fs +++ b/tests/authoring/Inline/SubstitutionMutations.fs @@ -26,6 +26,7 @@ sub: * M.M: {{versions.stack | M.M }} * M: {{versions.stack | M }} * M+1: {{versions.stack | M+1 }} +* M-1: {{versions.stack | M-1 }} * M+1 | M.M: {{versions.stack | M+1 | M.M }} * M.M+1: {{versions.stack | M.M+1 }} * M.M-1: {{versions.stack | M.M-1 }} @@ -47,6 +48,7 @@ sub:
  • M.M: 9.1
  • M: 9
  • M+1: 10.0.0
  • +
  • M-1: 8.0.0
  • M+1 | M.M: 10.0
  • M.M+1: 9.2.0
  • M.M-1: 9.0.0