Skip to content

Commit

Permalink
+semver:major Added properties to ArchivingDlgViewModel to facilitate…
Browse files Browse the repository at this point in the history
… customizing the initial summary

Added unit tests and changed test app to illustrate intended usage of the new properties.
Improved/added some comments in ArchivingDlgViewModel
  • Loading branch information
tombogle committed Oct 4, 2024
1 parent f22556e commit f641213
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 20 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- [SIL.Windows.Forms.Archiving] Added public extensions class LinkLabelExtensions with some methods that were formerly in Extensions class (now in SIL.Archiving).
- [SIL.Archiving] Added public property isValid to IMDIPackage.
- [SIL.Archiving] Added public event InitializationFailed to IMDIArchivingDlgViewModel.
- [SIL.Archiving] Added the following properties to ArchivingDlgViewModel as an alternative way to customize the initial summary displayed: GetOverriddenPreArchivingMessages, InitialFileGroupDisplayMessageType, OverrideGetFileGroupDisplayMessage

### Changed

Expand Down Expand Up @@ -71,6 +72,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- [SIL.Archiving] Changed IArchivingSession.Files (and Session.Files) into an IReadonlyList.
- [SIL.Archiving] Made IMDIPackage.CreateIMDIPackage asynchronous, changing its signature to take a CancellationToken parameter and return Task<bool>.
- [SIL.Archiving] Made MetaTranscript.WriteCorpusImdiFile asynchronous, changing its signature to return Task<bool>.
- [SIL.Archiving] Changed the name of the third parameter in ArchivingDlgViewModel.AddFileGroup from progressMessage to addingToArchiveProgressMessage.

### Fixed
- [SIL.Archiving] Fixed typo in RampArchivingDlgViewModel for Ethnomusicology performance collection.
Expand Down
103 changes: 103 additions & 0 deletions SIL.Archiving.Tests/RampArchivingDlgViewModelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using SIL.IO;
using SIL.Reporting;
using SIL.TestUtilities;
using static SIL.Archiving.ArchivingDlgViewModel.MessageType;

namespace SIL.Archiving.Tests
{
Expand Down Expand Up @@ -737,4 +738,106 @@ private void IgnoreTestIfRampIsNotInstalled()
}
#endregion
}

[TestFixture]
[Category("Archiving")]
public class RampArchivingDlgViewModelWithOverrideDisplayInitialSummarySetTests
{
/// ------------------------------------------------------------------------------------
[Test]
public async Task DisplayInitialSummary_OverrideDisplayInitialSummaryIsSet_DefaultBehaviorOmitted()
{
ErrorReport.IsOkToInteractWithUser = false;

bool filesToArchiveCalled = false;

var model = new RampArchivingDlgViewModel("Test App", "Test Title", "tst",
(a, b) => { filesToArchiveCalled = true; }, (k, f) => throw new NotImplementedException());
var progress = new TestProgress("RAMP");
bool customSummaryShown = false;
model.OverrideDisplayInitialSummary = (d, c) => { customSummaryShown = true; };
bool otherDelegatesCalled = false;
model.GetOverriddenPreArchivingMessages = d =>
{
otherDelegatesCalled = true;
return new List<Tuple<string, ArchivingDlgViewModel.MessageType>>(0);
};

model.OverrideGetFileGroupDisplayMessage = s =>
{
otherDelegatesCalled = true;
return "frog lips";
};
await model.Initialize(progress, new CancellationToken());

Assert.True(filesToArchiveCalled);
Assert.True(customSummaryShown);
Assert.False(otherDelegatesCalled);
Assert.False(File.Exists(model.PackagePath));
}
}

[TestFixture]
[Category("Archiving")]
public class RampArchivingDlgViewModelWithFineGrainedOverridesForDisplayInitialSummarySetTests
{
/// ------------------------------------------------------------------------------------
[Test]
public async Task DisplayInitialSummary_OverridenPropertiesForDisplayInitialSummaryAreSet_MessagesReflectOverrides()
{
ErrorReport.IsOkToInteractWithUser = false;

void SetFilesToArchive(ArchivingDlgViewModel model, CancellationToken cancellationToken)
{
model.AddFileGroup(String.Empty, new[] { "green.frog" }, "These messages should not be displayed");
model.AddFileGroup("Toads", new[] { "red.toad", "blue.toad" }, "because in this test we do not create a package.");
}

var model = new RampArchivingDlgViewModel("Test App", "Test Title", "tst",
SetFilesToArchive, (k, f) => throw new NotImplementedException());

var messagesDisplayed = new List<Tuple<string, ArchivingDlgViewModel.MessageType>>();

void ModelOnOnReportMessage(string msg, ArchivingDlgViewModel.MessageType type)
{
messagesDisplayed.Add(new Tuple<string, ArchivingDlgViewModel.MessageType>(msg, type));
}

model.OnReportMessage += ModelOnOnReportMessage;

IEnumerable<Tuple<string, ArchivingDlgViewModel.MessageType>> GetMessages(IDictionary<string, Tuple<IEnumerable<string>, string>> arg)
{
yield return new Tuple<string, ArchivingDlgViewModel.MessageType>(
"First pre-archiving message", Warning);
yield return new Tuple<string, ArchivingDlgViewModel.MessageType>(
"Second pre-archiving message", Indented);
}

model.GetOverriddenPreArchivingMessages = GetMessages;
model.InitialFileGroupDisplayMessageType = Success;
model.OverrideGetFileGroupDisplayMessage = s => (s == String.Empty) ? "Frogs" : $"Label: {s}";


var progress = new TestProgress("RAMP");
await model.Initialize(progress, new CancellationToken());

Assert.That(messagesDisplayed.Count, Is.EqualTo(8));
Assert.That(messagesDisplayed[0].Item1, Is.EqualTo("Test implementation message for SearchingForArchiveUploadingProgram"));
Assert.That(messagesDisplayed[1].Item1, Is.EqualTo("First pre-archiving message"));
Assert.That(messagesDisplayed[1].Item2, Is.EqualTo(Warning));
Assert.That(messagesDisplayed[2].Item1, Is.EqualTo("Second pre-archiving message"));
Assert.That(messagesDisplayed[2].Item2, Is.EqualTo(Indented));
Assert.That(messagesDisplayed[3].Item1, Is.EqualTo("Frogs"));
Assert.That(messagesDisplayed[3].Item2, Is.EqualTo(Success));
Assert.That(messagesDisplayed[4].Item1, Is.EqualTo("green.frog"));
Assert.That(messagesDisplayed[4].Item2, Is.EqualTo(Bullet));
Assert.That(messagesDisplayed[5].Item1, Is.EqualTo("Label: Toads"));
Assert.That(messagesDisplayed[5].Item2, Is.EqualTo(Success));
Assert.That(messagesDisplayed[6].Item1, Is.EqualTo("red.toad"));
Assert.That(messagesDisplayed[6].Item2, Is.EqualTo(Bullet));
Assert.That(messagesDisplayed[7].Item1, Is.EqualTo("blue.toad"));
Assert.That(messagesDisplayed[7].Item2, Is.EqualTo(Bullet));
Assert.False(File.Exists(model.PackagePath));
}
}
}
102 changes: 83 additions & 19 deletions SIL.Archiving/ArchivingDlgViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public enum MessageType
Error,
/// <summary>Non-bold, indented with tab</summary>
Detail,
/// <summary>New line</summary>
/// <summary>Like Normal, but with preceding new line</summary>
Progress,
/// <summary>Non-bold, indented 8 spaces, with bullet character (U+00B7)</summary>
Bullet,
Expand Down Expand Up @@ -210,11 +210,52 @@ public enum MessageType

/// ------------------------------------------------------------------------------------
/// <summary>
/// Callback to allow application to handle display of initial summary in log box. If
/// Callback to allow application to handle display of initial summary (in log box). If
/// the application implements this, then the default summary display will be suppressed.
/// </summary>
/// ------------------------------------------------------------------------------------
public Action<IDictionary<string, Tuple<IEnumerable<string>, string>>, CancellationToken> OverrideDisplayInitialSummary { private get; set; }

/// ------------------------------------------------------------------------------------
/// <summary>
/// Delegate function that can be set to override the default pre-archiving message
/// shown in <see cref="DisplayInitialSummary"/>. By default, only a single message (as
/// determined by the <see cref="IArchivingProgressDisplay.GetMessage"/>) is displayed,
/// so this override is particularly useful if an application needs to display more than
/// one message before the archival creation begins.
/// </summary>
/// <remarks>This is used only in the normal default implementation of
/// <see cref="DisplayInitialSummary"/></remarks>, so if
/// <see cref="OverrideDisplayInitialSummary"/> is set, then there is no point in also
/// setting this delegate.
/// ------------------------------------------------------------------------------------
public Func<IDictionary<string, Tuple<IEnumerable<string>, string>>, IEnumerable<Tuple<string, MessageType>>> GetOverriddenPreArchivingMessages { private get; set; }

/// ------------------------------------------------------------------------------------
/// <summary>
/// This can be set to override the default <see cref="MessageType"/> used for displaying
/// information about each file group in <see cref="DisplayInitialSummary"/>. The default
/// type is <see cref="MessageType.Indented"/>.
/// </summary>
/// <remarks>This is used only in the normal default implementation of
/// <see cref="DisplayInitialSummary"/></remarks>, so if
/// <see cref="OverrideDisplayInitialSummary"/> is set, then there is no point in also
/// setting this property.
/// ------------------------------------------------------------------------------------
public MessageType InitialFileGroupDisplayMessageType { private get; set; } = MessageType.Indented;

/// ------------------------------------------------------------------------------------
/// <summary>
/// Delegate function that can be set to override the default "message" displayed for
/// file groups in <see cref="DisplayInitialSummary"/>. The default is simply the file
/// groupId (as set in <see cref="AddFileGroup"/>.
/// </summary>
/// <remarks>This is used only in the normal default implementation of
/// <see cref="DisplayInitialSummary"/></remarks>, so if
/// <see cref="OverrideDisplayInitialSummary"/> is set, then there is no point in also
/// setting this delegate.
/// ------------------------------------------------------------------------------------
public Func<string, string> OverrideGetFileGroupDisplayMessage { private get; set; }
#endregion

#region construction and initialization
Expand All @@ -225,8 +266,8 @@ public enum MessageType
/// <param name="id">Identifier (used as filename) for the package being created</param>
/// <param name="setFilesToArchive">Delegate to request client to call methods to set
/// which files should be archived (this is deferred to allow display of progress
/// message). Clients will normally do this by calling AddFileGroup one or more times.
/// </param>
/// message). Clients will normally do this by calling <see cref="AddFileGroup"/> one or
/// more times.</param>
/// ------------------------------------------------------------------------------------
protected ArchivingDlgViewModel(string appName, string title, string id,
Action<ArchivingDlgViewModel, CancellationToken> setFilesToArchive)
Expand Down Expand Up @@ -268,41 +309,64 @@ await Task.Run(() =>
public abstract int CalculateMaxProgressBarValue();

/// ------------------------------------------------------------------------------------
public virtual void AddFileGroup(string groupId, IEnumerable<string> files, string progressMessage)
/// <summary>
/// Adds a group of related files to be included when creating the archive package.
/// </summary>
/// <param name="groupId">A string that uniquely identifies the group of files.</param>
/// <param name="files">The collection fo files (paths)</param>
/// <param name="addingToArchiveProgressMessage">A progress message that would be
/// appropriate to display (if relevant to the type of archive package) when the file is
/// actually being added.</param>
/// <exception cref="ArgumentException">Thrown if a duplicate file group ID is specified
/// </exception>
/// ------------------------------------------------------------------------------------
public virtual void AddFileGroup(string groupId, IEnumerable<string> files,
string addingToArchiveProgressMessage)
{
Guard.AgainstNull(groupId, nameof(groupId));
if (FileLists.ContainsKey(groupId))
throw new ArgumentException("Duplicate file group ID: " + groupId, nameof(groupId));
FileLists[groupId] = Tuple.Create(files, progressMessage);
FileLists[groupId] = Tuple.Create(files, addingToArchiveProgressMessage);
}

/// ------------------------------------------------------------------------------------
private void DisplayInitialSummary(CancellationToken cancellationToken)
{
if (OverrideDisplayInitialSummary != null)
{
OverrideDisplayInitialSummary(FileLists, cancellationToken);
return;
}

foreach (var message in AdditionalMessages)
DisplayMessage(message.Key + "\n", message.Value);

if (GetOverriddenPreArchivingMessages != null)
{
foreach (var msg in GetOverriddenPreArchivingMessages(FileLists))
ReportProgress(msg.Item1, msg.Item2, cancellationToken);
}
else
ReportProgress(Progress.GetMessage(StringId.PreArchivingStatus), MessageType.Normal,
cancellationToken);

foreach (var kvp in FileLists)
{
ReportProgress(Progress.GetMessage(StringId.PreArchivingStatus), MessageType.Normal, cancellationToken);
if (cancellationToken.IsCancellationRequested)
throw new OperationCanceledException();

if (OnReportMessage != null)
{
foreach (var kvp in FileLists)
{
string msg = FileGroupDisplayMessage(kvp.Key);
if (msg != Empty)
OnReportMessage(msg, MessageType.Indented);
string msg = FileGroupDisplayMessage(kvp.Key);
if (msg != Empty)
DisplayMessage(msg, InitialFileGroupDisplayMessageType);

foreach (var file in kvp.Value.Item1)
OnReportMessage(Path.GetFileName(file), MessageType.Bullet);
}
}
foreach (var file in kvp.Value.Item1)
DisplayMessage(Path.GetFileName(file), MessageType.Bullet);
}
}

protected virtual string FileGroupDisplayMessage(string groupKey)
{
return groupKey;
return OverrideGetFileGroupDisplayMessage == null ? groupKey : OverrideGetFileGroupDisplayMessage(groupKey);
}
#endregion

Expand Down
11 changes: 10 additions & 1 deletion TestApps/ArchivingTestApp/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,17 @@ private void m_btnRamp_Click(object sender, EventArgs e)
var title = GetTitle();
var model = new RampArchivingDlgViewModel(kAppName, title,
title.ToLatinOnly("~", "_", ""), SetFilesToArchive, GetFileDescription);
if (ModifierKeys == Keys.Shift)
{
model.OverrideGetFileGroupDisplayMessage = s => $"override: {s}";
model.GetOverriddenPreArchivingMessages = d =>
new[] {new Tuple<string, ArchivingDlgViewModel.MessageType>($"Count: {d.Count}", ArchivingDlgViewModel.MessageType.Error) };
model.InitialFileGroupDisplayMessageType =
ArchivingDlgViewModel.MessageType.Warning;
}

using (var rampArchiveDlg = new ArchivingDlg(model, LocalizationManager.GetString(
"ArchivingTestApp.MainForm.AdditionalArchiveProcessInfo", "This is just a test.")))
"ArchivingTestApp.MainForm.AdditionalArchiveProcessInfo", "This is just a test.")))
{
rampArchiveDlg.ShowDialog(this);
}
Expand Down

0 comments on commit f641213

Please sign in to comment.