Skip to content

Commit

Permalink
feat(acc): add migration
Browse files Browse the repository at this point in the history
  • Loading branch information
nanikit committed Aug 31, 2024
1 parent efecccf commit 90adc0c
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 21 deletions.
33 changes: 33 additions & 0 deletions BetterSort.Accuracy.Test/ImportIntegrationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using BetterSort.Accuracy.Installers;
using BetterSort.Accuracy.Test.Mocks;
using BetterSort.Common.Test;
using BetterSort.Common.Test.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
using System.Threading.Tasks;
Expand All @@ -15,6 +16,7 @@ public class ImportIntegrationTest {
private readonly UnifiedImporter _importer;
private readonly MockProgress _progress;
private readonly InMemoryJsonRepository _repository;
private readonly MockLogger _logger;

public ImportIntegrationTest() {
var container = new DiContainer();
Expand All @@ -29,6 +31,7 @@ public ImportIntegrationTest() {
_importer = container.Resolve<UnifiedImporter>();
_progress = container.Resolve<MockProgress>();
_repository = container.Resolve<InMemoryJsonRepository>();
_logger = container.Resolve<MockLogger>();
}

[TestMethod]
Expand All @@ -41,5 +44,35 @@ public async Task TestImport() {
Assert.IsTrue(_progress.Progresses.Count > 1);
Assert.IsNull(_progress.Progresses.Last()!.Ratio);
}


[TestMethod]
public async Task TestMigration() {
_repository.Json = """
{
"bestRecords": [],
"lastRecordAt": "2024-08-31T06:28:58.3694439Z",
"version": "2.1.0.0"
}
""";

string? reason = await _importer.GetImportReason().ConfigureAwait(false);
Assert.AreEqual("There are breaking changes between 2.1.0.0 and 2.2. Reimport from online.", reason);
}


[TestMethod]
public async Task TestNoMigration() {
_repository.Json = """
{
"bestRecords": [],
"lastRecordAt": "2024-08-31T06:28:58.3694439Z",
"version": "2.2.0.0"
}
""";

string? reason = await _importer.GetImportReason().ConfigureAwait(false);
Assert.IsNull(reason);
}
}
}
2 changes: 1 addition & 1 deletion BetterSort.Accuracy/BetterSort.Accuracy.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
<GenerateManifest>True</GenerateManifest>
<PluginId>BetterSort.Accuracy</PluginId>
<PluginName>BetterSort.Accuracy</PluginName>
<Version>2.1.$(BeatmodsPatchNumber)</Version>
<Version>2.2.$(BeatmodsPatchNumber)</Version>
<Description>Add accuracy sort to BetterSongList</Description>
</PropertyGroup>

Expand Down
35 changes: 19 additions & 16 deletions BetterSort.Accuracy/External/AccuracyRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,45 @@ public interface IAccuracyRepository {
Task Save(SorterData accuracies);

Task<SorterData?> Load();

Task<StoredData?> LoadWithMetadata();
}

public class AccuracyRepository(SiraLog logger, IAccuracyJsonRepository jsonRepository, IClock clock) : IAccuracyRepository {
private SorterData? _cache;

public Task Save(SorterData accuracies) {
var (json, data) = GetPersistentData(accuracies, clock.Now);
jsonRepository.Save(json);

logger.Info($"Saved {data.BestRecords.Count} records");
_cache = accuracies;

return Task.CompletedTask;
}

public Task<SorterData?> Load() {
if (_cache != null) {
logger.Trace($"Load from cache.");
return Task.FromResult<SorterData?>(_cache);
public Task<StoredData?> LoadWithMetadata() {
string? json = jsonRepository.Load();
if (json == null) {
logger.Debug($"Attempted to load but play history is not exist.");
return Task.FromResult<StoredData?>(null);
}

var data = JsonConvert.DeserializeObject<StoredData>(json);
logger.Info($"Loaded {data?.BestRecords?.Count.ToString() ?? "no"} records");

return Task.FromResult(data);
}

public async Task<SorterData?> Load() {
try {
string? json = jsonRepository.Load();
if (json == null) {
logger.Debug($"Attempted to load but play history is not exist.");
return Task.FromResult<SorterData?>(null);
var data = await LoadWithMetadata().ConfigureAwait(false);
if (data == null) {
return null;
}

var data = JsonConvert.DeserializeObject<StoredData>(json);
logger.Info($"Loaded {data?.BestRecords?.Count.ToString() ?? "no"} records");

return Task.FromResult<SorterData?>(GetSorterData(data?.BestRecords));
return GetSorterData(data.BestRecords);
}
catch (Exception exception) {
logger.Warn(exception);
return Task.FromResult<SorterData?>(null);
return null;
}
}

Expand Down
24 changes: 20 additions & 4 deletions BetterSort.Accuracy/External/UnifiedImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,28 @@ public class UnifiedImporter(
private int _fetchedPages;

public async Task CollectOrImport() {
var data = await repository.Load().ConfigureAwait(false);
if (data != null) {
return;
string? importReason = await GetImportReason().ConfigureAwait(false);
if (importReason != null) {
logger.Info(importReason);
await ImportAndSave().ConfigureAwait(false);
}
}

public async Task<string?> GetImportReason() {
var data = await repository.LoadWithMetadata().ConfigureAwait(false);
if (data == null) {
return "Local history is not found. Import from online.";
}

var breakingChangeVersion = new Version(2, 2);
if (Version.TryParse(data.Version, out var version) && version < breakingChangeVersion) {
return $"There are breaking changes between {data.Version} and {breakingChangeVersion}. Reimport from online.";
}

return null;
}

logger.Info("Local history is not found. Import from online.");
private async Task ImportAndSave() {
var records = await CollectRecordsFromOnline().ConfigureAwait(false);
await repository.Save(records).ConfigureAwait(false);
}
Expand Down
1 change: 1 addition & 0 deletions BetterSort.Common.Test/MockEnvironmentInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public MockEnvironmentInstaller() {

public override void InstallBindings() {
Container.BindInterfacesAndSelfTo<Logger>().FromInstance(_logger).AsSingle();
Container.BindInterfacesAndSelfTo<MockLogger>().FromInstance(_logger).AsSingle();
Container.BindInterfacesAndSelfTo<SiraLog>().FromInstance(new MockSiraLog(_logger)).AsSingle();
Container.BindInterfacesAndSelfTo<FixedClock>().AsSingle();
Container.BindInterfacesAndSelfTo<MockBeatleader>().AsSingle();
Expand Down

0 comments on commit 90adc0c

Please sign in to comment.