From 9dcd9cb00ec16047fba57e7c0c99982553380048 Mon Sep 17 00:00:00 2001 From: Gavin Roudebush Date: Fri, 24 May 2024 11:12:25 -0400 Subject: [PATCH 1/2] Fixed an off by 1 issue related to maxmium GeneratorId. Max generator id was being calculated as 1 higher than the actual max. This has been corrected and the message in the exception thrown when the given generator id is invalid has been appropriately re-worded to include 0 and maxGeneratorId. --- IdGen/IdGenerator.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IdGen/IdGenerator.cs b/IdGen/IdGenerator.cs index 6da2173..2a7d907 100644 --- a/IdGen/IdGenerator.cs +++ b/IdGen/IdGenerator.cs @@ -55,11 +55,11 @@ public IdGenerator(int generatorId, IdGeneratorOptions options) _generatorid = generatorId; Options = options ?? throw new ArgumentNullException(nameof(options)); - var maxgeneratorid = 1U << Options.IdStructure.GeneratorIdBits; + var maxgeneratorid = (1U << Options.IdStructure.GeneratorIdBits) - 1; - if (_generatorid < 0 || _generatorid >= maxgeneratorid) + if (_generatorid < 0 || _generatorid > maxgeneratorid) { - throw new ArgumentOutOfRangeException(nameof(generatorId), $"GeneratorId must be between 0 and {maxgeneratorid - 1}."); + throw new ArgumentOutOfRangeException(nameof(generatorId), $"GeneratorId must be from 0 to {maxgeneratorid}."); } // Precalculate some values From 88e89082fea6c4a8bef9c3f2c13db66188dc43c8 Mon Sep 17 00:00:00 2001 From: Gavin Roudebush Date: Fri, 24 May 2024 21:42:57 -0400 Subject: [PATCH 2/2] Added unit tests for generator id max/min boundaries with +/- 1 variants --- IdGenTests/IdGeneratorTests.cs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/IdGenTests/IdGeneratorTests.cs b/IdGenTests/IdGeneratorTests.cs index 64e2529..d676a10 100644 --- a/IdGenTests/IdGeneratorTests.cs +++ b/IdGenTests/IdGeneratorTests.cs @@ -78,16 +78,36 @@ public void GeneratorId_ShouldBeMasked_WhenReadFromProperty() Assert.AreEqual((1 << g.Options.IdStructure.GeneratorIdBits) - 1, g.Id); } + [TestMethod] + public void Constructor_DoesNotThrow_OnMaxGeneratorId() + { + var structure = new IdStructure(41, 10, 12); + // 1023 is the max generator id for 10 bits. + var maxgeneratorid = 1023; + new IdGenerator(maxgeneratorid, new IdGeneratorOptions(structure)); + } + + [TestMethod] + public void Constructor_DoesNotThrow_OnGeneratorId_0() + { + new IdGenerator(0, new IdGeneratorOptions(new IdStructure(41, 10, 12))); + } + [TestMethod] [ExpectedException(typeof(ArgumentNullException))] public void Constructor_Throws_OnNull_Options() => new IdGenerator(1024, null!); - [TestMethod] [ExpectedException(typeof(ArgumentOutOfRangeException))] - public void Constructor_Throws_OnInvalidGeneratorId_Positive() - => new IdGenerator(1024, new IdGeneratorOptions(new IdStructure(41, 10, 12))); + public void Constructor_Throws_OnInvalidGeneratorId_Positive_MaxPlusOne() + { + var structure = new IdStructure(41, 10, 12); + // 1023 is the max generator id for 10 bits. + var maxgeneratorid = 1023; + int maxPlusOne = maxgeneratorid + 1; + new IdGenerator(maxPlusOne, new IdGeneratorOptions(structure)); + } [TestMethod] [ExpectedException(typeof(ArgumentOutOfRangeException))]