From 3561ad51bfad221601f4f30f2ccd967001dd5989 Mon Sep 17 00:00:00 2001 From: Nikolay Pozdnichenko Date: Sun, 8 Dec 2024 16:01:23 +0600 Subject: [PATCH] Add Binding and BindingMode enums Also added and refactored unit tests. --- .../Attributes/BindingAttriubuteTests.cs | 38 +++++++++ .../Attributes/BindingModeAttributeTests.cs | 38 +++++++++ .../Attributes/LinkAttributeTests.cs | 38 +++++++++ Libiada.Core.Tests/Core/BindingModeTests.cs | 79 +++++++++++++++++++ Libiada.Core.Tests/Core/BindingTests.cs | 77 ++++++++++++++++++ Libiada.Core.Tests/Core/LinkTests.cs | 36 +++------ .../Core/SimpleTypes/AccidentalTests.cs | 35 +++----- .../Core/SimpleTypes/FmotifTypeTests.cs | 33 +++----- .../Core/SimpleTypes/InstrumentTests.cs | 36 +++------ .../Core/SimpleTypes/NoteSymbolTests.cs | 50 +++++------- .../Core/SimpleTypes/TieTests.cs | 36 +++------ .../Music/MusicXml/MusicXmlParserTests.cs | 26 +++--- .../Music/PauseTreatmentTests.cs | 72 +++++++++++++++-- Libiada.Core.Tests/Music/SystemData.cs | 12 --- Libiada.Core/Attributes/BindingAttribute.cs | 21 +++++ .../Attributes/BindingModeAttribute.cs | 21 +++++ Libiada.Core/Attributes/LinkAttribute.cs | 4 +- Libiada.Core/Core/Binding.cs | 37 +++++++++ Libiada.Core/Core/BindingMode.cs | 45 +++++++++++ .../CongenericCalculators/Depth.cs | 4 +- Libiada.Core/Core/Link.cs | 17 ++++ 21 files changed, 568 insertions(+), 187 deletions(-) create mode 100644 Libiada.Core.Tests/Attributes/BindingAttriubuteTests.cs create mode 100644 Libiada.Core.Tests/Attributes/BindingModeAttributeTests.cs create mode 100644 Libiada.Core.Tests/Attributes/LinkAttributeTests.cs create mode 100644 Libiada.Core.Tests/Core/BindingModeTests.cs create mode 100644 Libiada.Core.Tests/Core/BindingTests.cs delete mode 100644 Libiada.Core.Tests/Music/SystemData.cs create mode 100644 Libiada.Core/Attributes/BindingAttribute.cs create mode 100644 Libiada.Core/Attributes/BindingModeAttribute.cs create mode 100644 Libiada.Core/Core/Binding.cs create mode 100644 Libiada.Core/Core/BindingMode.cs diff --git a/Libiada.Core.Tests/Attributes/BindingAttriubuteTests.cs b/Libiada.Core.Tests/Attributes/BindingAttriubuteTests.cs new file mode 100644 index 00000000..76ca410e --- /dev/null +++ b/Libiada.Core.Tests/Attributes/BindingAttriubuteTests.cs @@ -0,0 +1,38 @@ +namespace Libiada.Core.Tests.Attributes; + +using Libiada.Core.Attributes; +using Libiada.Core.Extensions; +using Libiada.Core.Core; + +/// +/// The binding attribute tests. +/// +[TestFixture(TestOf = typeof(BindingAttribute))] +public class BindingAttributeTests +{ + /// + /// Invalid binding value test. + /// + [Test] + public void InvalidBindingValueTest() + { + Assert.Throws(() => new BindingAttribute((Binding)3)); + } + + /// + /// Binding attribute value test. + /// + /// + /// The value. + /// + [Test] + public void BindingAttributeValueTest([Values] Binding value) + { + BindingAttribute attribute = new(value); + Assert.Multiple(() => + { + Assert.That(attribute.Value, Is.EqualTo(value)); + Assert.That(attribute.Value.GetDisplayValue(), Is.EqualTo(value.GetDisplayValue())); + }); + } +} diff --git a/Libiada.Core.Tests/Attributes/BindingModeAttributeTests.cs b/Libiada.Core.Tests/Attributes/BindingModeAttributeTests.cs new file mode 100644 index 00000000..40b773f0 --- /dev/null +++ b/Libiada.Core.Tests/Attributes/BindingModeAttributeTests.cs @@ -0,0 +1,38 @@ +namespace Libiada.Core.Tests.Attributes; + +using Libiada.Core.Attributes; +using Libiada.Core.Extensions; +using Libiada.Core.Core; + +/// +/// The binding mode attribute tests. +/// +[TestFixture(TestOf = typeof(BindingModeAttribute))] +public class BindingModeAttributeTests +{ + /// + /// Invalid binding mode value test. + /// + [Test] + public void InvalidBindingModeValueTest() + { + Assert.Throws(() => new BindingModeAttribute((BindingMode)5)); + } + + /// + /// Binding mode attribute value test. + /// + /// + /// The value. + /// + [Test] + public void BindingModeAttributeValueTest([Values] BindingMode value) + { + BindingModeAttribute attribute = new(value); + Assert.Multiple(() => + { + Assert.That(attribute.Value, Is.EqualTo(value)); + Assert.That(attribute.Value.GetDisplayValue(), Is.EqualTo(value.GetDisplayValue())); + }); + } +} diff --git a/Libiada.Core.Tests/Attributes/LinkAttributeTests.cs b/Libiada.Core.Tests/Attributes/LinkAttributeTests.cs new file mode 100644 index 00000000..3d40ab06 --- /dev/null +++ b/Libiada.Core.Tests/Attributes/LinkAttributeTests.cs @@ -0,0 +1,38 @@ +namespace Libiada.Core.Tests.Attributes; + +using Libiada.Core.Attributes; +using Libiada.Core.Extensions; +using Libiada.Core.Core; + +/// +/// The link attribute tests. +/// +[TestFixture(TestOf = typeof(LinkAttribute))] +public class LinkAttributeTests +{ + /// + /// Invalid link value test. + /// + [Test] + public void InvalidLinkValueTest() + { + Assert.Throws(() => new LinkAttribute((Link)8)); + } + + /// + /// Link attribute value test. + /// + /// + /// The value. + /// + [Test] + public void LinkAttributeValueTest([Values] Link value) + { + LinkAttribute attribute = new(value); + Assert.Multiple(() => + { + Assert.That(attribute.Value, Is.EqualTo(value)); + Assert.That(attribute.Value.GetDisplayValue(), Is.EqualTo(value.GetDisplayValue())); + }); + } +} diff --git a/Libiada.Core.Tests/Core/BindingModeTests.cs b/Libiada.Core.Tests/Core/BindingModeTests.cs new file mode 100644 index 00000000..6fa54b15 --- /dev/null +++ b/Libiada.Core.Tests/Core/BindingModeTests.cs @@ -0,0 +1,79 @@ +namespace Libiada.Core.Tests.Core; + +using Libiada.Core.Core; +using Libiada.Core.Extensions; + +/// +/// BindingMode enum tests. +/// +[TestFixture(TestOf = typeof(BindingMode))] +public class BindingModeTests +{ + /// + /// Binding modes count. + /// + private const int BindingModesCount = 5; + + /// + /// Array of all binding modes. + /// + private readonly BindingMode[] bindingModes = EnumExtensions.ToArray(); + + /// + /// Tests count of binding modes. + /// + [Test] + public void BindingModeCountTest() => Assert.That(bindingModes, Has.Length.EqualTo(BindingModesCount)); + + /// + /// Tests values of binding modes. + /// + [Test] + public void BindingModeValuesTest() + { + for (int i = 0; i < BindingModesCount; i++) + { + Assert.That(bindingModes, Contains.Item((BindingMode)i)); + } + } + + /// + /// Tests names of binding modes. + /// + /// + /// The binding mode. + /// + /// + /// The name. + /// + [TestCase((BindingMode)0, "NotApplicable")] + [TestCase((BindingMode)1, "Normal")] + [TestCase((BindingMode)2, "Cyclic")] + [TestCase((BindingMode)3, "Lossy")] + [TestCase((BindingMode)4, "Redundant")] + public void BindingModeNamesTest(BindingMode bindingMode, string name) => Assert.That(bindingMode.GetName(), Is.EqualTo(name)); + + /// + /// Tests that all binding modes have display value. + /// + /// + /// The binding mode. + /// + [Test] + public void BindingModeHasDisplayValueTest([Values] BindingMode bindingMode) => Assert.That(bindingMode.GetDisplayValue(), Is.Not.Empty); + + /// + /// Tests that all binding modes have description. + /// + /// + /// The binding mode. + /// + [Test] + public void BindingModeHasDescriptionTest([Values] BindingMode bindingMode) => Assert.That(bindingMode.GetDescription(), Is.Not.Empty); + + /// + /// Tests that all binding modes values are unique. + /// + [Test] + public void BindingModeValuesUniqueTest() => Assert.That(bindingModes.Cast(), Is.Unique); +} diff --git a/Libiada.Core.Tests/Core/BindingTests.cs b/Libiada.Core.Tests/Core/BindingTests.cs new file mode 100644 index 00000000..37c257f6 --- /dev/null +++ b/Libiada.Core.Tests/Core/BindingTests.cs @@ -0,0 +1,77 @@ +namespace Libiada.Core.Tests.Core; + +using Libiada.Core.Core; +using Libiada.Core.Extensions; + +/// +/// Binding enum tests. +/// +[TestFixture(TestOf = typeof(Binding))] +public class BindingTests +{ + /// + /// Bindings count. + /// + private const int BindingsCount = 3; + + /// + /// Array of all bindings. + /// + private readonly Binding[] bindings = EnumExtensions.ToArray(); + + /// + /// Tests count of bindings. + /// + [Test] + public void BindingCountTest() => Assert.That(bindings, Has.Length.EqualTo(BindingsCount)); + + /// + /// Tests values of bindings. + /// + [Test] + public void BindingValuesTest() + { + for (int i = 0; i < BindingsCount; i++) + { + Assert.That(bindings, Contains.Item((Binding)i)); + } + } + + /// + /// Tests names of bindings. + /// + /// + /// The binding. + /// + /// + /// The name. + /// + [TestCase((Binding)0, "NotApplicable")] + [TestCase((Binding)1, "Beginning")] + [TestCase((Binding)2, "End")] + public void BindingNamesTest(Binding binding, string name) => Assert.That(binding.GetName(), Is.EqualTo(name)); + + /// + /// Tests that all bindings have display value. + /// + /// + /// The binding. + /// + [Test] + public void BindingHasDisplayValueTest([Values] Binding binding) => Assert.That(binding.GetDisplayValue(), Is.Not.Empty); + + /// + /// Tests that all bindings have description. + /// + /// + /// The binding. + /// + [Test] + public void BindingHasDescriptionTest([Values] Binding binding) => Assert.That(binding.GetDescription(), Is.Not.Empty); + + /// + /// Tests that all bindings values are unique. + /// + [Test] + public void BindingValuesUniqueTest() => Assert.That(bindings.Cast(), Is.Unique); +} diff --git a/Libiada.Core.Tests/Core/LinkTests.cs b/Libiada.Core.Tests/Core/LinkTests.cs index 32286abd..95b35789 100644 --- a/Libiada.Core.Tests/Core/LinkTests.cs +++ b/Libiada.Core.Tests/Core/LinkTests.cs @@ -14,15 +14,16 @@ public class LinkTests /// private const int LinksCount = 8; + /// + /// Array of all links. + /// + private readonly Link[] links = EnumExtensions.ToArray(); + /// /// Tests count of links. /// [Test] - public void LinkCountTest() - { - int actualCount = EnumExtensions.ToArray().Length; - Assert.That(EnumExtensions.ToArray(), Has.Length.EqualTo(LinksCount)); - } + public void LinkCountTest() => Assert.That(links, Has.Length.EqualTo(LinksCount)); /// /// Tests values of links. @@ -30,10 +31,9 @@ public void LinkCountTest() [Test] public void LinkValuesTest() { - Link[] links = EnumExtensions.ToArray(); for (int i = 0; i < LinksCount; i++) { - Assert.That(links, Does.Contain((Link)i)); + Assert.That(links, Contains.Item((Link)i)); } } @@ -54,10 +54,7 @@ public void LinkValuesTest() [TestCase((Link)5, "Cycle")] [TestCase((Link)6, "CycleStart")] [TestCase((Link)7, "CycleEnd")] - public void LinkNamesTest(Link link, string name) - { - Assert.That(link.GetName(), Is.EqualTo(name)); - } + public void LinkNamesTest(Link link, string name) => Assert.That(link.GetName(), Is.EqualTo(name)); /// /// Tests that all links have display value. @@ -66,10 +63,7 @@ public void LinkNamesTest(Link link, string name) /// The link. /// [Test] - public void LinkHasDisplayValueTest([Values]Link link) - { - Assert.That(link.GetDisplayValue(), Is.Not.Empty); - } + public void LinkHasDisplayValueTest([Values] Link link) => Assert.That(link.GetDisplayValue(), Is.Not.Empty); /// /// Tests that all links have description. @@ -78,19 +72,11 @@ public void LinkHasDisplayValueTest([Values]Link link) /// The link. /// [Test] - public void LinkHasDescriptionTest([Values]Link link) - { - Assert.That(link.GetDescription(), Is.Not.Empty); - } + public void LinkHasDescriptionTest([Values] Link link) => Assert.That(link.GetDescription(), Is.Not.Empty); /// /// Tests that all links values are unique. /// [Test] - public void LinkValuesUniqueTest() - { - Link[] links = EnumExtensions.ToArray(); - IEnumerable linkValues = links.Cast(); - Assert.That(linkValues, Is.Unique); - } + public void LinkValuesUniqueTest() => Assert.That(links.Cast(), Is.Unique); } diff --git a/Libiada.Core.Tests/Core/SimpleTypes/AccidentalTests.cs b/Libiada.Core.Tests/Core/SimpleTypes/AccidentalTests.cs index 0d302ba6..7f7d2f8a 100644 --- a/Libiada.Core.Tests/Core/SimpleTypes/AccidentalTests.cs +++ b/Libiada.Core.Tests/Core/SimpleTypes/AccidentalTests.cs @@ -14,14 +14,16 @@ public class AccidentalTests /// private const int AccidentalsCount = 5; + /// + /// Array of all accidentals. + /// + private readonly Accidental[] accidentals = EnumExtensions.ToArray(); + /// /// Tests count of accidentals. /// [Test] - public void AccidentalCountTest() - { - Assert.That(EnumExtensions.ToArray(), Has.Length.EqualTo(AccidentalsCount)); - } + public void AccidentalCountTest() => Assert.That(accidentals, Has.Length.EqualTo(AccidentalsCount)); /// /// Tests values of accidentals. @@ -29,10 +31,9 @@ public void AccidentalCountTest() [Test] public void AccidentalValuesTest() { - Accidental[] accidentals = EnumExtensions.ToArray(); for (int i = -2; i < AccidentalsCount - 2; i++) { - Assert.That(accidentals, Does.Contain((Accidental)i)); + Assert.That(accidentals, Contains.Item((Accidental)i)); } } @@ -50,10 +51,7 @@ public void AccidentalValuesTest() [TestCase((Accidental)0, "Bekar")] [TestCase((Accidental)1, "Sharp")] [TestCase((Accidental)2, "DoubleSharp")] - public void AccidentalNamesTest(Accidental accidental, string name) - { - Assert.That(accidental.GetName(), Is.EqualTo(name)); - } + public void AccidentalNamesTest(Accidental accidental, string name) => Assert.That(accidental.GetName(), Is.EqualTo(name)); /// /// Tests that all accidentals have display value. @@ -62,10 +60,7 @@ public void AccidentalNamesTest(Accidental accidental, string name) /// The accidental. /// [Test] - public void AccidentalHasDisplayValueTest([Values]Accidental accidental) - { - Assert.That(accidental.GetDisplayValue(), Is.Not.Empty); - } + public void AccidentalHasDisplayValueTest([Values] Accidental accidental) => Assert.That(accidental.GetDisplayValue(), Is.Not.Empty); /// /// Tests that all accidentals have description. @@ -74,19 +69,11 @@ public void AccidentalHasDisplayValueTest([Values]Accidental accidental) /// The accidental. /// [Test] - public void AccidentalHasDescriptionTest([Values]Accidental accidental) - { - Assert.That(accidental.GetDescription(), Is.Not.Empty); - } + public void AccidentalHasDescriptionTest([Values] Accidental accidental) => Assert.That(accidental.GetDescription(), Is.Not.Empty); /// /// Tests that all accidentals values are unique. /// [Test] - public void AccidentalValuesUniqueTest() - { - Accidental[] accidentals = EnumExtensions.ToArray(); - IEnumerable accidentalValues = accidentals.Cast(); - Assert.That(accidentalValues, Is.Unique); - } + public void AccidentalValuesUniqueTest() => Assert.That(accidentals.Cast(), Is.Unique); } diff --git a/Libiada.Core.Tests/Core/SimpleTypes/FmotifTypeTests.cs b/Libiada.Core.Tests/Core/SimpleTypes/FmotifTypeTests.cs index f9204fd7..81db109e 100644 --- a/Libiada.Core.Tests/Core/SimpleTypes/FmotifTypeTests.cs +++ b/Libiada.Core.Tests/Core/SimpleTypes/FmotifTypeTests.cs @@ -14,14 +14,18 @@ public class FmotifTypeTests /// private const int FmotifTypesCount = 6; + /// + /// Array of all fmotif types. + /// + private readonly FmotifType[] fmotifTypes = EnumExtensions.ToArray(); + /// /// Tests count of fmotif types. /// [Test] public void FmotifTypeCountTest() { - int actualCount = EnumExtensions.ToArray().Length; - Assert.That(actualCount, Is.EqualTo(FmotifTypesCount)); + Assert.That(fmotifTypes, Has.Length.EqualTo(FmotifTypesCount)); } /// @@ -30,10 +34,9 @@ public void FmotifTypeCountTest() [Test] public void FmotifTypeValuesTest() { - FmotifType[] fmotifTypes = EnumExtensions.ToArray(); for (int i = 0; i < FmotifTypesCount; i++) { - Assert.That(fmotifTypes, Does.Contain((FmotifType)i)); + Assert.That(fmotifTypes, Contains.Item((FmotifType)i)); } } @@ -52,10 +55,7 @@ public void FmotifTypeValuesTest() [TestCase((FmotifType)3, "IncreasingSequence")] [TestCase((FmotifType)4, "CompleteMinimalMetrorhythmicGroup")] [TestCase((FmotifType)5, "PartialMinimalMetrorhythmicGroup")] - public void FmotifTypeNamesTest(FmotifType fmotifType, string name) - { - Assert.That(fmotifType.GetName(), Is.EqualTo(name)); - } + public void FmotifTypeNamesTest(FmotifType fmotifType, string name) => Assert.That(fmotifType.GetName(), Is.EqualTo(name)); /// /// Tests that all fmotif types have display value. @@ -64,10 +64,7 @@ public void FmotifTypeNamesTest(FmotifType fmotifType, string name) /// The fmotif type. /// [Test] - public void FmotifTypeHasDisplayValueTest([Values]FmotifType fmotifType) - { - Assert.That(fmotifType.GetDisplayValue(), Is.Not.Empty); - } + public void FmotifTypeHasDisplayValueTest([Values] FmotifType fmotifType) => Assert.That(fmotifType.GetDisplayValue(), Is.Not.Empty); /// /// Tests that all fmotif types have description. @@ -76,19 +73,11 @@ public void FmotifTypeHasDisplayValueTest([Values]FmotifType fmotifType) /// The fmotif type. /// [Test] - public void FmotifTypeHasDescriptionTest([Values]FmotifType fmotifType) - { - Assert.That(fmotifType.GetDescription(), Is.Not.Empty); - } + public void FmotifTypeHasDescriptionTest([Values] FmotifType fmotifType) => Assert.That(fmotifType.GetDescription(), Is.Not.Empty); /// /// Tests that all fmotif types values are unique. /// [Test] - public void FmotifTypeValuesUniqueTest() - { - FmotifType[] fmotifTypes = EnumExtensions.ToArray(); - IEnumerable fmotifTypeValues = fmotifTypes.Cast(); - Assert.That(fmotifTypeValues, Is.Unique); - } + public void FmotifTypeValuesUniqueTest() => Assert.That(fmotifTypes.Cast(), Is.Unique); } diff --git a/Libiada.Core.Tests/Core/SimpleTypes/InstrumentTests.cs b/Libiada.Core.Tests/Core/SimpleTypes/InstrumentTests.cs index 316f23f4..df55194d 100644 --- a/Libiada.Core.Tests/Core/SimpleTypes/InstrumentTests.cs +++ b/Libiada.Core.Tests/Core/SimpleTypes/InstrumentTests.cs @@ -14,15 +14,16 @@ public class InstrumentTests /// private const int InstrumentsCount = 1; + /// + /// Array of all instruments. + /// + private readonly Instrument[] instruments = EnumExtensions.ToArray(); + /// /// Tests count of instruments. /// [Test] - public void InstrumentCountTest() - { - int actualCount = EnumExtensions.ToArray().Length; - Assert.That(actualCount, Is.EqualTo(InstrumentsCount)); - } + public void InstrumentCountTest() => Assert.That(instruments, Has.Length.EqualTo(InstrumentsCount)); /// /// Tests values of instruments. @@ -30,10 +31,9 @@ public void InstrumentCountTest() [Test] public void InstrumentValuesTest() { - Instrument[] instruments = EnumExtensions.ToArray(); for (int i = 0; i < InstrumentsCount; i++) { - Assert.That(instruments, Does.Contain((Instrument)i)); + Assert.That(instruments, Contains.Item((Instrument)i)); } } @@ -47,10 +47,7 @@ public void InstrumentValuesTest() /// The name. /// [TestCase((Instrument)0, "AnyOrUnknown")] - public void InstrumentNamesTest(Instrument instrument, string name) - { - Assert.That(instrument.GetName(), Is.EqualTo(name)); - } + public void InstrumentNamesTest(Instrument instrument, string name) => Assert.That(instrument.GetName(), Is.EqualTo(name)); /// /// Tests that all instruments have display value. @@ -59,10 +56,7 @@ public void InstrumentNamesTest(Instrument instrument, string name) /// The instrument. /// [Test] - public void InstrumentHasDisplayValueTest([Values]Instrument instrument) - { - Assert.That(instrument.GetDisplayValue(), Is.Not.Empty); - } + public void InstrumentHasDisplayValueTest([Values] Instrument instrument) => Assert.That(instrument.GetDisplayValue(), Is.Not.Empty); /// /// Tests that all instruments have description. @@ -71,19 +65,11 @@ public void InstrumentHasDisplayValueTest([Values]Instrument instrument) /// The instrument. /// [Test] - public void InstrumentHasDescriptionTest([Values]Instrument instrument) - { - Assert.That(instrument.GetDescription(), Is.Not.Empty); - } + public void InstrumentHasDescriptionTest([Values] Instrument instrument) => Assert.That(instrument.GetDescription(), Is.Not.Empty); /// /// Tests that all instruments values are unique. /// [Test] - public void InstrumentValuesUniqueTest() - { - Instrument[] instruments = EnumExtensions.ToArray(); - IEnumerable instrumentValues = instruments.Cast(); - Assert.That(instrumentValues, Is.Unique); - } + public void InstrumentValuesUniqueTest() => Assert.That(instruments.Cast(), Is.Unique); } diff --git a/Libiada.Core.Tests/Core/SimpleTypes/NoteSymbolTests.cs b/Libiada.Core.Tests/Core/SimpleTypes/NoteSymbolTests.cs index 21d2f164..72a96874 100644 --- a/Libiada.Core.Tests/Core/SimpleTypes/NoteSymbolTests.cs +++ b/Libiada.Core.Tests/Core/SimpleTypes/NoteSymbolTests.cs @@ -14,14 +14,16 @@ public class NoteSymbolTests /// private const int NoteSymbolsCount = 7; + /// + /// Array of all note symbols. + /// + private readonly NoteSymbol[] noteSymbols = EnumExtensions.ToArray(); + /// /// Tests count of note symbols. /// [Test] - public void NoteSymbolCountTest() - { - Assert.That(EnumExtensions.ToArray(), Has.Length.EqualTo(NoteSymbolsCount)); - } + public void NoteSymbolCountTest() => Assert.That(noteSymbols, Has.Length.EqualTo(NoteSymbolsCount)); /// /// Tests values of note symbols. @@ -29,14 +31,16 @@ public void NoteSymbolCountTest() [Test] public void NoteSymbolValuesTest() { - NoteSymbol[] noteSymbols = EnumExtensions.ToArray(); - Assert.That(noteSymbols, Does.Contain((NoteSymbol)0)); - Assert.That(noteSymbols, Does.Contain((NoteSymbol)2)); - Assert.That(noteSymbols, Does.Contain((NoteSymbol)4)); - Assert.That(noteSymbols, Does.Contain((NoteSymbol)5)); - Assert.That(noteSymbols, Does.Contain((NoteSymbol)7)); - Assert.That(noteSymbols, Does.Contain((NoteSymbol)9)); - Assert.That(noteSymbols, Does.Contain((NoteSymbol)11)); + Assert.Multiple(() => + { + Assert.That(noteSymbols, Contains.Item((NoteSymbol)0)); + Assert.That(noteSymbols, Contains.Item((NoteSymbol)2)); + Assert.That(noteSymbols, Contains.Item((NoteSymbol)4)); + Assert.That(noteSymbols, Contains.Item((NoteSymbol)5)); + Assert.That(noteSymbols, Contains.Item((NoteSymbol)7)); + Assert.That(noteSymbols, Contains.Item((NoteSymbol)9)); + Assert.That(noteSymbols, Contains.Item((NoteSymbol)11)); + }); } /// @@ -55,10 +59,7 @@ public void NoteSymbolValuesTest() [TestCase((NoteSymbol)7, "G")] [TestCase((NoteSymbol)9, "A")] [TestCase((NoteSymbol)11, "B")] - public void NoteSymbolNamesTest(NoteSymbol noteSymbol, string name) - { - Assert.That(noteSymbol.GetName(), Is.EqualTo(name)); - } + public void NoteSymbolNamesTest(NoteSymbol noteSymbol, string name) => Assert.That(noteSymbol.GetName(), Is.EqualTo(name)); /// /// Tests that all note symbols have display value. @@ -67,10 +68,7 @@ public void NoteSymbolNamesTest(NoteSymbol noteSymbol, string name) /// The note symbol. /// [Test] - public void NoteSymbolHasDisplayValueTest([Values]NoteSymbol noteSymbol) - { - Assert.That(noteSymbol.GetDisplayValue(), Is.Not.Empty); - } + public void NoteSymbolHasDisplayValueTest([Values] NoteSymbol noteSymbol) => Assert.That(noteSymbol.GetDisplayValue(), Is.Not.Empty); /// /// Tests that all note symbols have description. @@ -79,19 +77,11 @@ public void NoteSymbolHasDisplayValueTest([Values]NoteSymbol noteSymbol) /// The note symbol. /// [Test] - public void NoteSymbolHasDescriptionTest([Values]NoteSymbol noteSymbol) - { - Assert.That(noteSymbol.GetDescription(), Is.Not.Empty); - } + public void NoteSymbolHasDescriptionTest([Values] NoteSymbol noteSymbol) => Assert.That(noteSymbol.GetDescription(), Is.Not.Empty); /// /// Tests that all note symbols values are unique. /// [Test] - public void NoteSymbolValuesUniqueTest() - { - NoteSymbol[] noteSymbols = EnumExtensions.ToArray(); - IEnumerable noteSymbolValues = noteSymbols.Cast(); - Assert.That(noteSymbolValues, Is.Unique); - } + public void NoteSymbolValuesUniqueTest() => Assert.That(noteSymbols.Cast(), Is.Unique); } diff --git a/Libiada.Core.Tests/Core/SimpleTypes/TieTests.cs b/Libiada.Core.Tests/Core/SimpleTypes/TieTests.cs index 99ae4428..66d0a84d 100644 --- a/Libiada.Core.Tests/Core/SimpleTypes/TieTests.cs +++ b/Libiada.Core.Tests/Core/SimpleTypes/TieTests.cs @@ -14,15 +14,16 @@ public class TieTests /// private const int TiesCount = 4; + /// + /// Array of all ties. + /// + private readonly Tie[] ties = EnumExtensions.ToArray(); + /// /// Tests count of ties. /// [Test] - public void TieCountTest() - { - int actualCount = EnumExtensions.ToArray().Length; - Assert.That(actualCount, Is.EqualTo(TiesCount)); - } + public void TieCountTest() => Assert.That(ties, Has.Length.EqualTo(TiesCount)); /// /// Tests values of ties. @@ -30,10 +31,9 @@ public void TieCountTest() [Test] public void TieValuesTest() { - Tie[] ties = EnumExtensions.ToArray(); for (int i = 0; i < TiesCount; i++) { - Assert.That(ties, Does.Contain((Tie)i)); + Assert.That(ties, Contains.Item((Tie)i)); } } @@ -50,10 +50,7 @@ public void TieValuesTest() [TestCase((Tie)1, "Start")] [TestCase((Tie)2, "End")] [TestCase((Tie)3, "Continue")] - public void TieNamesTest(Tie tie, string name) - { - Assert.That(tie.GetName(), Is.EqualTo(name)); - } + public void TieNamesTest(Tie tie, string name) => Assert.That(tie.GetName(), Is.EqualTo(name)); /// /// Tests that all ties have display value. @@ -62,10 +59,7 @@ public void TieNamesTest(Tie tie, string name) /// The tie. /// [Test] - public void TieHasDisplayValueTest([Values]Tie tie) - { - Assert.That(tie.GetDisplayValue(), Is.Not.Empty); - } + public void TieHasDisplayValueTest([Values] Tie tie) => Assert.That(tie.GetDisplayValue(), Is.Not.Empty); /// /// Tests that all ties have description. @@ -74,19 +68,11 @@ public void TieHasDisplayValueTest([Values]Tie tie) /// The tie. /// [Test] - public void TieHasDescriptionTest([Values]Tie tie) - { - Assert.That(tie.GetDescription(), Is.Not.Empty); - } + public void TieHasDescriptionTest([Values] Tie tie) => Assert.That(tie.GetDescription(), Is.Not.Empty); /// /// Tests that all ties values are unique. /// [Test] - public void TieValuesUniqueTest() - { - Tie[] ties = EnumExtensions.ToArray(); - IEnumerable tieValues = ties.Cast(); - Assert.That(tieValues, Is.Unique); - } + public void TieValuesUniqueTest() => Assert.That(ties.Cast(), Is.Unique); } diff --git a/Libiada.Core.Tests/Music/MusicXml/MusicXmlParserTests.cs b/Libiada.Core.Tests/Music/MusicXml/MusicXmlParserTests.cs index ce2db544..e9a5c1ba 100644 --- a/Libiada.Core.Tests/Music/MusicXml/MusicXmlParserTests.cs +++ b/Libiada.Core.Tests/Music/MusicXml/MusicXmlParserTests.cs @@ -15,6 +15,8 @@ public class MusicXmlParserTests /// private ScoreTrack scoreTrack; + private readonly string TestDataFolderPath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles"); + /// /// The music xml parser set up. /// @@ -94,7 +96,7 @@ public void MusicXmlParserSetUp() [Test] public void XmlParserTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "LibiadaMusicExample7Liga.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "LibiadaMusicExample7Liga.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); @@ -121,7 +123,7 @@ public void XmlParserTest() [Test] public void PolyXmlParserTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "PolyTest.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "PolyTest.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); @@ -156,7 +158,7 @@ public void PolyXmlParserTest() [Test] public void RepeaterTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "RepeaterTest.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "RepeaterTest.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); @@ -176,7 +178,7 @@ public void RepeaterTest() [Test] public void XmlParserScoreTrackTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "LibiadaMusicExample7Liga.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "LibiadaMusicExample7Liga.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); @@ -190,7 +192,7 @@ public void XmlParserScoreTrackTest() [Test] public void XmlParserCongenericScoreTrackTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "LibiadaMusicExample7Liga.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "LibiadaMusicExample7Liga.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); @@ -204,7 +206,7 @@ public void XmlParserCongenericScoreTrackTest() [Test] public void XmlParserMeasureTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "LibiadaMusicExample7Liga.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "LibiadaMusicExample7Liga.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); @@ -224,7 +226,7 @@ public void XmlParserMeasureTest() [Test] public void XmlParserNoteTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "LibiadaMusicExample7Liga.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "LibiadaMusicExample7Liga.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); @@ -250,7 +252,7 @@ public void XmlParserNoteTest() [Test] public void XmlParserAttributesTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "LibiadaMusicExample7Liga.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "LibiadaMusicExample7Liga.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); @@ -274,7 +276,7 @@ public void XmlParserAttributesTest() [Test] public void XmlParserPitchTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "LibiadaMusicExample7Liga.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "LibiadaMusicExample7Liga.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); @@ -304,7 +306,7 @@ public void XmlParserPitchTest() [Test] public void XmlParserDurationTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "LibiadaMusicExample7Liga.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "LibiadaMusicExample7Liga.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); @@ -330,7 +332,7 @@ public void XmlParserDurationTest() [Test] public void XmlParserTieTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "LibiadaMusicExample7Liga.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "LibiadaMusicExample7Liga.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); @@ -356,7 +358,7 @@ public void XmlParserTieTest() [Test] public void XmlParserTripletTest() { - string xmlFilePath = Path.Join(TestContext.CurrentContext.TestDirectory, "Music", "XmlTestFiles", "LibiadaMusicExample7Liga.xml"); + string xmlFilePath = Path.Join(TestDataFolderPath, "LibiadaMusicExample7Liga.xml"); MusicXmlReader xmlReader = new(xmlFilePath); MusicXmlParser parser = new(); parser.Execute(xmlReader.MusicXmlDocument); diff --git a/Libiada.Core.Tests/Music/PauseTreatmentTests.cs b/Libiada.Core.Tests/Music/PauseTreatmentTests.cs index 05a32079..2b9d1e70 100644 --- a/Libiada.Core.Tests/Music/PauseTreatmentTests.cs +++ b/Libiada.Core.Tests/Music/PauseTreatmentTests.cs @@ -1,22 +1,78 @@ namespace Libiada.Core.Tests.Music; +using Libiada.Core.Extensions; using Libiada.Core.Music; /// -/// The param pause treatment tests. +/// PauseTreatment enum tests. /// -[TestFixture] +[TestFixture(TestOf = typeof(PauseTreatment))] public class PauseTreatmentTests { /// - /// The param pause test. + /// The pause treatments count. + /// + private const int PauseTreatmentsCount = 4; + + /// + /// Array of all pause treatments. + /// + private readonly PauseTreatment[] pauseTreatments = EnumExtensions.ToArray(); + + /// + /// Tests count of pause treatments. /// [Test] - public void ParamPauseTest() + public void PauseTreatmentCountTest() => Assert.That(pauseTreatments, Has.Length.EqualTo(PauseTreatmentsCount)); + + /// + /// Tests values of pause treatments. + /// + [Test] + public void PauseTreatmentValuesTest() { - // TODO: Rewrite this as other enum tests - Assert.That((int)PauseTreatment.Ignore, Is.EqualTo(1)); - Assert.That((int)PauseTreatment.NoteTrace, Is.EqualTo(2)); - Assert.That((int)PauseTreatment.SilenceNote, Is.EqualTo(3)); + for (int i = 0; i < PauseTreatmentsCount; i++) + { + Assert.That(pauseTreatments, Contains.Item((PauseTreatment)i)); + } } + + /// + /// Tests names of pause treatments. + /// + /// + /// The pause treatment. + /// + /// + /// The name. + /// + [TestCase((PauseTreatment)0, "NotApplicable")] + [TestCase((PauseTreatment)1, "Ignore")] + [TestCase((PauseTreatment)2, "NoteTrace")] + [TestCase((PauseTreatment)3, "SilenceNote")] + public void PauseTreatmentNamesTest(PauseTreatment pauseTreatment, string name) => Assert.That(pauseTreatment.GetName(), Is.EqualTo(name)); + + /// + /// Tests that all pause treatments have display value. + /// + /// + /// The pause treatment. + /// + [Test] + public void PauseTreatmentHasDisplayValueTest([Values] PauseTreatment pauseTreatment) => Assert.That(pauseTreatment.GetDisplayValue(), Is.Not.Empty); + + /// + /// Tests that all pause treatments have description. + /// + /// + /// The pause treatment. + /// + [Test] + public void PauseTreatmentHasDescriptionTest([Values] PauseTreatment pauseTreatment) => Assert.That(pauseTreatment.GetDescription(), Is.Not.Empty); + + /// + /// Tests that all pause treatments values are unique. + /// + [Test] + public void PauseTreatmentValuesUniqueTest() => Assert.That(pauseTreatments.Cast(), Is.Unique); } diff --git a/Libiada.Core.Tests/Music/SystemData.cs b/Libiada.Core.Tests/Music/SystemData.cs deleted file mode 100644 index 011493ee..00000000 --- a/Libiada.Core.Tests/Music/SystemData.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Libiada.Core.Tests.Music; - -/// -/// The system data. -/// -public static class SystemData -{ - /// - /// The bin folder path. - /// - public static readonly string ProjectFolderPath = $"{TestContext.CurrentContext.TestDirectory}/../../../music/"; -} diff --git a/Libiada.Core/Attributes/BindingAttribute.cs b/Libiada.Core/Attributes/BindingAttribute.cs new file mode 100644 index 00000000..5b773747 --- /dev/null +++ b/Libiada.Core/Attributes/BindingAttribute.cs @@ -0,0 +1,21 @@ +namespace Libiada.Core.Attributes; + +using System; + +using Libiada.Core.Core; + +[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] +public class BindingAttribute : Attribute +{ + public readonly Binding Value; + + public BindingAttribute(Binding value) + { + if (!Enum.IsDefined(value)) + { + throw new ArgumentException("Binding attribute value is not valid binding", nameof(value)); + } + + Value = value; + } +} diff --git a/Libiada.Core/Attributes/BindingModeAttribute.cs b/Libiada.Core/Attributes/BindingModeAttribute.cs new file mode 100644 index 00000000..7586000f --- /dev/null +++ b/Libiada.Core/Attributes/BindingModeAttribute.cs @@ -0,0 +1,21 @@ +namespace Libiada.Core.Attributes; + +using System; + +using Libiada.Core.Core; + +[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] +public class BindingModeAttribute : Attribute +{ + public readonly BindingMode Value; + + public BindingModeAttribute(BindingMode value) + { + if (!Enum.IsDefined(value)) + { + throw new ArgumentException("Binding mode attribute value is not valid binding mode", nameof(value)); + } + + Value = value; + } +} diff --git a/Libiada.Core/Attributes/LinkAttribute.cs b/Libiada.Core/Attributes/LinkAttribute.cs index 8a802376..90e592bf 100644 --- a/Libiada.Core/Attributes/LinkAttribute.cs +++ b/Libiada.Core/Attributes/LinkAttribute.cs @@ -4,14 +4,14 @@ using Libiada.Core.Core; -[AttributeUsage(AttributeTargets.Field)] +[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] public class LinkAttribute : Attribute { public readonly Link Value; public LinkAttribute(Link value) { - if (!Enum.IsDefined(typeof(Link), value)) + if (!Enum.IsDefined(value)) { throw new ArgumentException("Link attribute value is not valid link", nameof(value)); } diff --git a/Libiada.Core/Core/Binding.cs b/Libiada.Core/Core/Binding.cs new file mode 100644 index 00000000..b42486b3 --- /dev/null +++ b/Libiada.Core/Core/Binding.cs @@ -0,0 +1,37 @@ +namespace Libiada.Core.Core; + +using System.ComponentModel.DataAnnotations; +using System.ComponentModel; + +public enum Binding : byte +{ + /// + /// Binding is not applied in characteristic calculation (or otherwise). + /// If passed to intervals manager exception will be thrown. + /// + [Display(Name = "Binding not applicable")] + [Description("Binding can not be applied")] + NotApplicable = 0, + + /// + /// Binding to the start of the sequence. + /// Interval from the beginning of the sequence + /// to the first element occurrence is taken into account. + /// And Interval from the last element occurrence + /// to the end of the sequence is not taken into account. + /// + [Display(Name = "Binding to the beginning")] + [Description("Interval from the start of the sequence to the first occurrence of the element is taken into account")] + Beginning = 1, + + /// + /// Binding to the end of the sequence. + /// And Interval from the last element occurrence + /// to the end of the sequence is taken into account. + /// And Interval from the beginning of the sequence + /// to the first element occurrence is not taken into account. + /// + [Display(Name = "To the end")] + [Description("Interval from the last occurrence of the element to the end of the sequence is taken into account")] + End = 2 +} diff --git a/Libiada.Core/Core/BindingMode.cs b/Libiada.Core/Core/BindingMode.cs new file mode 100644 index 00000000..66869525 --- /dev/null +++ b/Libiada.Core/Core/BindingMode.cs @@ -0,0 +1,45 @@ +namespace Libiada.Core.Core; + +using System.ComponentModel.DataAnnotations; +using System.ComponentModel; + +public enum BindingMode : byte +{ + /// + /// Binding mode is not applied in characteristic calculation (or otherwise). + /// If passed to intervals manager exception will be thrown. + /// + [Display(Name = "Binding mode not applicable")] + [Description("Binding mode can not be applied")] + NotApplicable = 0, + + /// + /// With normal binding mode each element gets one corresponding interval. + /// + [Display(Name = "Normal binding mode")] + [Description("Each element gets one corresponding interval")] + Normal = 1, + + /// + /// Cyclic binding mode closes sequence into a loop and each element gets one corresponding interval. + /// + [Display(Name = "Cyclic binding mode")] + [Description("Сloses sequence into a loop and each element gets one corresponding interval")] + Cyclic = 2, + + /// + /// With lossy binding mode only intervals between elements are taken into account. + /// And no interval to the either end of the sequence is considered. + /// + [Display(Name = "Lossy binding mode")] + [Description("Only intervals between elements are taken into account")] + Lossy = 3, + + /// + /// With redundant binding mode intervals to the both ends of the sequence are taken into account. + /// And nubber of intervals is greater than number of elements. + /// + [Display(Name = "Redundant binding mode")] + [Description("Intervals to the both ends of the sequence are taken into account")] + Redundant = 4 +} diff --git a/Libiada.Core/Core/Characteristics/Calculators/CongenericCalculators/Depth.cs b/Libiada.Core/Core/Characteristics/Calculators/CongenericCalculators/Depth.cs index 77cc9837..7628ef07 100644 --- a/Libiada.Core/Core/Characteristics/Calculators/CongenericCalculators/Depth.cs +++ b/Libiada.Core/Core/Characteristics/Calculators/CongenericCalculators/Depth.cs @@ -1,7 +1,7 @@ -using System.Numerics; - namespace Libiada.Core.Core.Characteristics.Calculators.CongenericCalculators; +using System.Numerics; + /// /// Characteristic of chain depth. /// diff --git a/Libiada.Core/Core/Link.cs b/Libiada.Core/Core/Link.cs index 6c62b0a1..225621c1 100644 --- a/Libiada.Core/Core/Link.cs +++ b/Libiada.Core/Core/Link.cs @@ -1,5 +1,6 @@ namespace Libiada.Core.Core; +using Libiada.Core.Attributes; using System.ComponentModel; using System.ComponentModel.DataAnnotations; @@ -14,6 +15,8 @@ public enum Link : byte /// [Display(Name = "Not applied")] [Description("Link is not applied")] + [Binding(Binding.NotApplicable)] + [BindingMode(BindingMode.NotApplicable)] NotApplied = 0, /// @@ -24,6 +27,8 @@ public enum Link : byte /// [Display(Name = "None")] [Description(" The first and the last intervals to boundaries of sequence are not taken into account")] + [Binding(Binding.Beginning)] + [BindingMode(BindingMode.Lossy)] None = 1, /// @@ -33,6 +38,8 @@ public enum Link : byte /// [Display(Name = "To the beginning")] [Description("Interval from the start of the sequence to the first occurrence of the element is taken into account")] + [Binding(Binding.Beginning)] + [BindingMode(BindingMode.Normal)] Start = 2, /// @@ -42,6 +49,8 @@ public enum Link : byte /// [Display(Name = "To the end")] [Description("Interval from the last occurrence of the element to the end of the sequence is taken into account")] + [Binding(Binding.End)] + [BindingMode(BindingMode.Normal)] End = 3, /// @@ -53,6 +62,8 @@ public enum Link : byte [Display(Name = "To the beginning and to the end")] [Description("Both intervals from the start of the sequence to the first occurrence of the element " + "and from the last occurrence of the element to the end of the sequence are taken into account")] + [Binding(Binding.Beginning)] + [BindingMode(BindingMode.Redundant)] Both = 4, /// @@ -64,6 +75,8 @@ public enum Link : byte [Display(Name = "Cyclic")] [Description("Interval from the last occurrence of the element to the end of the sequence added " + "to the interval from the start of the sequence to the first occurrence of the element (as if sequence was cyclic)")] + [Binding(Binding.Beginning)] + [BindingMode(BindingMode.Cyclic)] Cycle = 5, /// @@ -73,6 +86,8 @@ public enum Link : byte /// [Display(Name = "Cyclic to the beginning")] [Description("Cyclic reading from left to right (intervals are bound to the right position (element occurrence))")] + [Binding(Binding.Beginning)] + [BindingMode(BindingMode.Cyclic)] CycleStart = 6, /// @@ -82,5 +97,7 @@ public enum Link : byte /// [Display(Name = "Cyclic to the end")] [Description("Cyclic reading from right to left (intervals are bound to the left position (element occurrence))")] + [Binding(Binding.End)] + [BindingMode(BindingMode.Cyclic)] CycleEnd = 7 }