Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 168 additions & 38 deletions Source/SmartMigrations/MigrationAttribute.cs

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions Source/SmartMigrations/SmartMigrations.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@
<PackageTags>database;migration;version;</PackageTags>
</PropertyGroup>

<ItemGroup>
<PackageReference Update="MinVer" Version="6.1.0-beta.1" />
</ItemGroup>


</Project>
161 changes: 161 additions & 0 deletions Tests/SmartMigrations.Test/MigrationAttributeListFromTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
namespace SmartMigrations.Test;

using SmartMigrations;
using Xunit;

public class MigrationAttributeListFromTests
{
#region Constructor: MigrationAttribute(int[] fromList, int to, bool shouldAvoid = false)

[Theory]
[InlineData(new int[] { 1 }, 5, false, new int[] { 1 }, 5, false, false)]
[InlineData(new int[] { 1, 3, 5 }, 10, true, new int[] { 1, 3, 5 }, 10, false, true)]
[InlineData(new int[] { 0, 1, 2 }, 3, false, new int[] { 0, 1, 2 }, 3, false, false)]
[InlineData(new int[] { 10, 20, 30, 40 }, 50, true, new int[] { 10, 20, 30, 40 }, 50, false, true)]
[InlineData(new int[] { 100 }, 200, false, new int[] { 100 }, 200, false, false)]
[InlineData(new int[] { 5, 1, 3 }, 10, false, new int[] { 5, 1, 3 }, 10, false, false)]
[InlineData(new int[] { 5, 1, 3, 1, 5 }, 10, true, new int[] { 5, 1, 3 }, 10, false, true)]
public void Constructor_DefaultSchema_ListFrom_Success(int[] fromList, int to, bool shouldAvoid, int[] expectedFromVersions, int expectedTo, bool expectedIsRange, bool expectedShouldAvoid)
{
var attribute = new MigrationAttribute(fromList, to, shouldAvoid);
Assert.Equal(expectedFromVersions, attribute.FromVersions);
Assert.Equal(expectedTo, attribute.ToVersion);
Assert.Equal(expectedIsRange, attribute.IsRange);
Assert.Equal(expectedShouldAvoid, attribute.ShouldAvoid);
Assert.Null(attribute.FromSchema);
Assert.Null(attribute.ToSchema);
}

[Theory]
[InlineData(new int[] { 1, 5 }, 5, false)]
[InlineData(new int[] { 7, -12 }, 7, false)]
[InlineData(new int[] { 7, -12 }, -12, true)]
[InlineData(new int[] { 10, 20, 30 }, 20, true)]
[InlineData(new int[] { 5 }, 5, false)]
public void Constructor_DefaultSchema_ListFrom_ContainsTo_ThrowsException(int[] fromList, int to, bool shouldAvoid)
{
Assert.Throws<ArgumentException>(() => new MigrationAttribute(fromList, to, shouldAvoid));
}

[Fact]
public void Constructor_DefaultSchema_ListFrom_NullList_ThrowsException()
{
Assert.Throws<ArgumentNullException>(() => new MigrationAttribute((int[])null!, 5));
}

#endregion

#region Constructor: MigrationAttribute(string? schema, int[] fromList, int to, bool shouldAvoid = false)

[Theory]
[InlineData(null, new int[] { 1 }, 5, false, new int[] { 1 }, 5, false, false)]
[InlineData(null, new int[] { 1 }, 5, true, new int[] { 1 }, 5, false, true)]
[InlineData("free", new int[] { 1, 2, 3 }, 10, false, new int[] { 1, 2, 3 }, 10, false, false)]
[InlineData("free", new int[] { 1, 2, 3 }, 10, true, new int[] { 1, 2, 3 }, 10, false, true)]
[InlineData("paid", new int[] { 5, 10, 15, 20 }, 25, false, new int[] { 5, 10, 15, 20 }, 25, false, false)]
[InlineData("paid", new int[] { 5, 10, 15, 20 }, 25, true, new int[] { 5, 10, 15, 20 }, 25, false, true)]
[InlineData("enterprise", new int[] { -10, -5, 0, 5, 10 }, 15, false, new int[] { -10, -5, 0, 5, 10 }, 15, false, false)]
[InlineData("enterprise", new int[] { -10, -5, 0, 5, 10 }, 15, true, new int[] { -10, -5, 0, 5, 10 }, 15, false, true)]
public void Constructor_SpecificSchema_ListFrom_Success(string? schema, int[] fromList, int to, bool shouldAvoid, int[] expectedFromVersions, int expectedTo, bool expectedIsRange, bool expectedShouldAvoid)
{
var attribute = new MigrationAttribute(schema, fromList, to, shouldAvoid);
Assert.Equal(expectedFromVersions, attribute.FromVersions);
Assert.Equal(expectedTo, attribute.ToVersion);
Assert.Equal(expectedIsRange, attribute.IsRange);
Assert.Equal(expectedShouldAvoid, attribute.ShouldAvoid);
Assert.Equal(schema, attribute.FromSchema);
Assert.Equal(schema, attribute.ToSchema);
}

[Theory]
[InlineData("", new int[] { 1 }, 5, false)]
[InlineData(" ", new int[] { 1 }, 5, false)]
[InlineData("\t", new int[] { 1 }, 5, false)]
[InlineData("\n", new int[] { 1 }, 5, false)]
public void Constructor_SpecificSchema_ListFrom_InvalidSchema_ThrowsException(string schema, int[] fromList, int to, bool shouldAvoid)
{
Assert.Throws<ArgumentException>(() => new MigrationAttribute(schema, fromList, to, shouldAvoid));
}

#endregion

#region Constructor: MigrationAttribute(string? fromSchema, int[] fromList, string? toSchema, int to, bool shouldAvoid = false)

[Theory]
[InlineData(null, new int[] { 1 }, null, 5, false, new int[] { 1 }, 5, false, false)]
[InlineData(null, new int[] { 1 }, null, 5, true, new int[] { 1 }, 5, false, true)]
[InlineData("free", new int[] { 1, 2, 3 }, "free", 10, false, new int[] { 1, 2, 3 }, 10, false, false)]
[InlineData("free", new int[] { 1, 2, 3 }, "free", 10, true, new int[] { 1, 2, 3 }, 10, false, true)]
[InlineData("free", new int[] { 5, 10, 15 }, "paid", 1, false, new int[] { 5, 10, 15 }, 1, false, false)]
[InlineData("free", new int[] { 5, 10, 15 }, "paid", 1, true, new int[] { 5, 10, 15 }, 1, false, true)]
[InlineData("paid", new int[] { 10, 20 }, "enterprise", 1, false, new int[] { 10, 20 }, 1, false, false)]
[InlineData("paid", new int[] { 10, 20 }, "enterprise", 1, true, new int[] { 10, 20 }, 1, false, true)]
[InlineData(null, new int[] { 5, 10 }, "premium", 1, false, new int[] { 5, 10 }, 1, false, false)]
[InlineData("basic", new int[] { 5, 10 }, null, 15, false, new int[] { 5, 10 }, 15, false, false)]
public void Constructor_CrossSchema_ListFrom_Success(string? fromSchema, int[] fromList, string? toSchema, int to, bool shouldAvoid, int[] expectedFromVersions, int expectedTo, bool expectedIsRange, bool expectedShouldAvoid)
{
var attribute = new MigrationAttribute(fromSchema, fromList, toSchema, to, shouldAvoid);
Assert.Equal(expectedFromVersions, attribute.FromVersions);
Assert.Equal(expectedTo, attribute.ToVersion);
Assert.Equal(expectedIsRange, attribute.IsRange);
Assert.Equal(expectedShouldAvoid, attribute.ShouldAvoid);
Assert.Equal(fromSchema, attribute.FromSchema);
Assert.Equal(toSchema, attribute.ToSchema);
}

[Theory]
[InlineData("", new int[] { 1 }, "paid", 5, false)]
[InlineData(" ", new int[] { 1 }, "paid", 5, false)]
[InlineData("free", new int[] { 1 }, "", 5, false)]
[InlineData("free", new int[] { 1 }, " ", 5, false)]
[InlineData("\t", new int[] { 1 }, "paid", 5, false)]
[InlineData("free", new int[] { 1 }, "\n", 5, false)]
public void Constructor_CrossSchema_ListFrom_InvalidSchema_ThrowsException(string fromSchema, int[] fromList, string toSchema, int to, bool shouldAvoid)
{
Assert.Throws<ArgumentException>(() => new MigrationAttribute(fromSchema, fromList, toSchema, to, shouldAvoid));
}

#endregion

#region Edge Cases for List From Migrations

[Fact]
public void Constructor_ListFrom_DuplicatesRemoved()
{
var attribute = new MigrationAttribute(new int[] { 1, 2, 2, 3, 1, 3 }, 10);
Assert.Equal(new int[] { 1, 2, 3 }, attribute.FromVersions);
}

[Fact]
public void Constructor_ListFrom_EmptyList()
{
var attribute = new MigrationAttribute(new int[] { }, 10);
Assert.Empty(attribute.FromVersions);
Assert.Equal(10, attribute.ToVersion);
}

[Fact]
public void Constructor_ListFrom_IsRangeFalse()
{
var attribute = new MigrationAttribute(new int[] { 1, 2, 3 }, 10);
Assert.False(attribute.IsRange);
}

[Fact]
public void Constructor_ListFrom_OrderPreserved()
{
var attribute = new MigrationAttribute(new int[] { 5, 1, 3, 2 }, 10);
Assert.Equal(new int[] { 5, 1, 3, 2 }, attribute.FromVersions);
}

[Fact]
public void Constructor_ListFrom_LargeList()
{
var largeList = Enumerable.Range(1, 100).ToArray();
var attribute = new MigrationAttribute(largeList, 200);
Assert.Equal(largeList, attribute.FromVersions);
Assert.Equal(200, attribute.ToVersion);
}

#endregion
}
74 changes: 74 additions & 0 deletions Tests/SmartMigrations.Test/MigrationAttributeNewSchemaTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
namespace SmartMigrations.Test;

using SmartMigrations;
using Xunit;

public class MigrationAttributeNewSchemaTests
{
#region Constructor: MigrationAttribute(int to, bool shouldAvoid = false)

[Theory]
[InlineData(0, false)]
[InlineData(0, true)]
[InlineData(1, false)]
[InlineData(1, true)]
[InlineData(30, null)]
[InlineData(30, true)]
[InlineData(int.MaxValue, false)]
[InlineData(int.MaxValue, true)]
public void Constructor_DefaultSchema_InitialSetup_Success(int to, bool? shouldAvoid)
{
var attribute = shouldAvoid != null
? new MigrationAttribute(to, shouldAvoid.Value)
: new MigrationAttribute(to);
Assert.Null(attribute.FromSchema);
Assert.Empty(attribute.FromVersions);
Assert.False(attribute.IsRange);
Assert.Null(attribute.ToSchema);
Assert.Equal(to, attribute.ToVersion);
if (shouldAvoid.HasValue) Assert.Equal(shouldAvoid.Value, attribute.ShouldAvoid);
else Assert.False(attribute.ShouldAvoid);
}

#endregion

#region Constructor: MigrationAttribute(string? schema, int to, bool shouldAvoid = false)

[Theory]
[InlineData(null, 0, false, null)]
[InlineData(null, 1, true, null)]
[InlineData("free", 0, false, "free")]
[InlineData("free", 135, true, "free")]
[InlineData("paid", 100, false, "paid")]
[InlineData("paid", -100, true, "paid")]
[InlineData("enterprise", int.MaxValue, false, "enterprise")]
[InlineData("enterprise", int.MaxValue, true, "enterprise")]
[InlineData("custom_schema", int.MinValue, false, "custom_schema")]
[InlineData("custom_schema", int.MinValue, true, "custom_schema")]
[InlineData(" a schema ", -315498, false, "a schema")]
[InlineData("\n\t\nsomeThing123 \n", 69420, true, "someThing123")]
public void Constructor_SpecificSchema_InitialSetup_Success(string? schema, int to, bool shouldAvoid, string? expectedSchema)
{
var attribute = new MigrationAttribute(schema, to, shouldAvoid);
Assert.Equal(expectedSchema, attribute.FromSchema);
Assert.Empty(attribute.FromVersions);
Assert.False(attribute.IsRange);
Assert.Equal(expectedSchema, attribute.ToSchema);
Assert.Equal(to, attribute.ToVersion);
Assert.Equal(shouldAvoid, attribute.ShouldAvoid);
}

[Theory]
[InlineData("", 1, false)]
[InlineData(" ", 1, true)]
[InlineData("\t", 1, false)]
[InlineData("\n", 1, true)]
[InlineData("\t \n", 1, false)]
[InlineData("\n\n\n \n", 1, true)]
public void Constructor_SpecificSchema_InitialSetup_InvalidSchema_ThrowsException(string schema, int to, bool shouldAvoid)
{
Assert.Throws<ArgumentException>(() => new MigrationAttribute(schema, to, shouldAvoid));
}

#endregion
}
Loading
Loading