internal void RunSortFilesAction() { _results = new FileComparisonResult[] { }; switch (_action) { case SortFilesAction.SearchDifferences: _results = SortFilesSearchDifferences.Go(_settings).ToArray(); break; case SortFilesAction.SearchDuplicates: _results = SortFilesSearchDuplicates.Go(_settings).ToArray(); break; case SortFilesAction.SearchDuplicatesInOneDir: _results = SortFilesSearchDuplicatesInOneDir.Go(_settings).ToArray(); break; default: Utils.MessageErr("Unrecognized action."); break; } // update UI on main thread WrapInvoke(() => { listView_ColumnClick(null, new ColumnClickEventArgs(0)); listView.Columns[1].Width = -2; // autosize to the longest item in the column lblAction.Text = _caption + Utils.NL; lblAction.Text += "" + _results.Length + " file(s) listed:"; }); }
static void TestMethod_TestFileOpFileSetWritetime() { var dir = TestUtil.GetTestSubDirectory("right_fndmved", true); var now = DateTime.UtcNow; var future = now.AddMinutes(25); var past = now.AddMinutes(-25); // re-use existing logic for fuzzy time comparison, // in case, say, we're running this test on a FAT drive with imprecise times. var settingsForTimeComparison = new SortFilesSettings(); settingsForTimeComparison.AllowFiletimesDifferForDST = false; settingsForTimeComparison.AllowFiletimesDifferForFAT = true; // set write-time to be the future, and undo. var path = dir + Utils.Sep + "testIntoFuture.txt"; File.WriteAllText(path, "testIntoFuture"); File.SetLastWriteTimeUtc(path, now); var op = new FileOpFileSetWritetime(path, now, future); op.Do(); TestUtil.IsTrue(SortFilesSearchDifferences.AreTimesEqual(future, File.GetLastWriteTimeUtc(path), settingsForTimeComparison)); op.Undo(); TestUtil.IsTrue(SortFilesSearchDifferences.AreTimesEqual(now, File.GetLastWriteTimeUtc(path), settingsForTimeComparison)); path = dir + Utils.Sep + "testIntoPast.txt"; File.WriteAllText(path, "testIntoPast"); File.SetLastWriteTimeUtc(path, now); op = new FileOpFileSetWritetime(path, now, past); op.Do(); TestUtil.IsTrue(SortFilesSearchDifferences.AreTimesEqual(past, File.GetLastWriteTimeUtc(path), settingsForTimeComparison)); op.Undo(); TestUtil.IsTrue(SortFilesSearchDifferences.AreTimesEqual(now, File.GetLastWriteTimeUtc(path), settingsForTimeComparison)); }
static void TestMethod_TestSearchMovedFiles() { var settings = new SortFilesSettings(); var left = TestUtil.GetTestSubDirectory("left_fndmved", true); var right = TestUtil.GetTestSubDirectory("right_fndmved", true); settings.LeftDirectory = left; settings.RightDirectory = right; // first, set up test files File.WriteAllText(left + Utils.Sep + "onlyleft.txt", "onlyL"); File.WriteAllText(left + Utils.Sep + "renamed1.txt", "renamed1"); File.WriteAllText(left + Utils.Sep + "renamed2.txt", "renamed2"); File.WriteAllText(left + Utils.Sep + "empty1.txt", ""); File.WriteAllText(left + Utils.Sep + "changed1.txt", "123"); File.WriteAllText(left + Utils.Sep + "same.txt", "s"); File.WriteAllText(right + Utils.Sep + "onlyright.txt", "onlyR"); File.WriteAllText(right + Utils.Sep + "renamed1.a", "renamed1"); File.WriteAllText(right + Utils.Sep + "renamed2.a", "renamed2"); File.WriteAllText(right + Utils.Sep + "empty1.a", ""); File.WriteAllText(right + Utils.Sep + "changed1.txt", "124"); File.WriteAllText(right + Utils.Sep + "same.txt", "s"); // set last-write-times var dtNow = DateTime.Now; foreach (var filename in Directory.EnumerateFiles(left).Concat( Directory.EnumerateFiles(right))) { File.SetLastWriteTimeUtc(filename, dtNow); } File.SetLastWriteTimeUtc(right + Utils.Sep + "changed1.txt", dtNow.AddDays(1)); // run search-for-differences var results = SortFilesSearchDifferences.Go(settings); var expectedDifferences = @"|empty1.a|Right |onlyright.txt|Right |renamed1.a|Right |renamed2.a|Right changed1.txt|changed1.txt|Changed empty1.txt||Left onlyleft.txt||Left renamed1.txt||Left renamed2.txt||Left"; CompareResultsToString(results, expectedDifferences); // run search for moved files var query = from item in results where item.Type == FileComparisonResultType.Left_Only select item; var resultsMoved = SortFilesSearchDuplicates.SearchMovedFiles( settings.LeftDirectory, settings.RightDirectory, query); TestUtil.IsEq(2, resultsMoved.Count); // the 0-length empty.txt isn't included in this list, we don't treat it as a duplicate TestUtil.IsEq(Utils.Sep + "renamed1.txt", resultsMoved[0].Item1.FileInfoLeft.Filename); TestUtil.IsEq(Utils.Sep + "renamed1.a", resultsMoved[0].Item2); TestUtil.IsEq(Utils.Sep + "renamed2.txt", resultsMoved[1].Item1.FileInfoLeft.Filename); TestUtil.IsEq(Utils.Sep + "renamed2.a", resultsMoved[1].Item2); }
static void TestMethod_TestSortFilesOperations() { // run the methods on actual files. first create combinations of modified/not modified. var settings = new SortFilesSettings(); settings.LeftDirectory = TestUtil.GetTestSubDirectory("left_fndmved", true); settings.RightDirectory = TestUtil.GetTestSubDirectory("right_fndmved", true); var filesCreated = CreateFileCombinations.Go( settings.LeftDirectory, settings.RightDirectory); TestUtil.IsEq( CreateFileCombinations.CountPossibleModifiedTimes() * CreateFileCombinations.CountPossibleContents() * CreateFileCombinations.CountPossibleFilenames() * ((1 * 2) + (3 * 2)), // ExtraCopies.None -> 2 files, the rest -> 3 files filesCreated); // search for duplicates in one dir, only ones it will find are 'extra copy on left.' var results = SortFilesSearchDuplicatesInOneDir.Go(settings); TestUtil.IsEq( CreateFileCombinations.CountPossibleModifiedTimes() * CreateFileCombinations.CountPossibleContents() * CreateFileCombinations.CountPossibleFilenames(), results.Count); // verify sort order. for each pair, the left side should sort first alphabetically var expectedDuplicates = @"MTimeAddTextMNameOneOnLeft.a|MTimeAddTextMNameOneOnLeft.a_1|Same_Contents MTimeAddTextSmNameOneOnLeft.a|MTimeAddTextSmNameOneOnLeft.a_1|Same_Contents MTimeAltTextMNameOneOnLeft.a|MTimeAltTextMNameOneOnLeft.a_1|Same_Contents MTimeAltTextSmNameOneOnLeft.a|MTimeAltTextSmNameOneOnLeft.a_1|Same_Contents MTimeSmTextMNameOneOnLeft.a|MTimeSmTextMNameOneOnLeft.a_1|Same_Contents MTimeSmTextSmNameOneOnLeft.a|MTimeSmTextSmNameOneOnLeft.a_1|Same_Contents SmTimeAddTextMNameOneOnLeft.a|SmTimeAddTextMNameOneOnLeft.a_1|Same_Contents SmTimeAddTextSmNameOneOnLeft.a|SmTimeAddTextSmNameOneOnLeft.a_1|Same_Contents SmTimeAltTextMNameOneOnLeft.a|SmTimeAltTextMNameOneOnLeft.a_1|Same_Contents SmTimeAltTextSmNameOneOnLeft.a|SmTimeAltTextSmNameOneOnLeft.a_1|Same_Contents SmTimeSmTextMNameOneOnLeft.a|SmTimeSmTextMNameOneOnLeft.a_1|Same_Contents SmTimeSmTextSmNameOneOnLeft.a|SmTimeSmTextSmNameOneOnLeft.a_1|Same_Contents"; CompareResultsToString(results, expectedDuplicates); // search for duplicates across directories // should find all files on the right marked 'SmText'. results = SortFilesSearchDuplicates.Go(settings); var countExpectedDuplicates = (from filename in Directory.EnumerateFiles(settings.RightDirectory) where filename.Contains("SmText") select filename).Count(); TestUtil.IsEq(countExpectedDuplicates, results.Count); // verify sort order expectedDuplicates = @"MTimeSmTextMNameNone.a|MTimeSmTextMNameNone.z|Same_Contents MTimeSmTextMNameOneOnLeft.a|MTimeSmTextMNameOneOnLeft.z|Same_Contents MTimeSmTextMNameOneOnRight.a|MTimeSmTextMNameOneOnRight.z|Same_Contents MTimeSmTextMNameOneOnRight.a|MTimeSmTextMNameOneOnRight.z_1|Same_Contents MTimeSmTextSmNameNone.a|MTimeSmTextSmNameNone.a|Same_Contents MTimeSmTextSmNameOneOnLeft.a|MTimeSmTextSmNameOneOnLeft.a|Same_Contents MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a|Same_Contents MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a_1|Same_Contents SmTimeSmTextMNameNone.a|SmTimeSmTextMNameNone.z|Same_Contents SmTimeSmTextMNameOneOnLeft.a|SmTimeSmTextMNameOneOnLeft.z|Same_Contents SmTimeSmTextMNameOneOnRight.a|SmTimeSmTextMNameOneOnRight.z|Same_Contents SmTimeSmTextMNameOneOnRight.a|SmTimeSmTextMNameOneOnRight.z_1|Same_Contents SmTimeSmTextSmNameNone.a|SmTimeSmTextSmNameNone.a|Same_Contents SmTimeSmTextSmNameOneOnLeft.a|SmTimeSmTextSmNameOneOnLeft.a|Same_Contents SmTimeSmTextSmNameOneOnRight.a|SmTimeSmTextSmNameOneOnRight.a|Same_Contents SmTimeSmTextSmNameOneOnRight.a|SmTimeSmTextSmNameOneOnRight.a_1|Same_Contents"; CompareResultsToString(results, expectedDuplicates); // search for duplicates across directories, but uses lmt as a shortcut (less thorough) // it will now think that the SmTimeAltText ones are equal because, // when it sees the lmt are the same, it treats them as the same and doesn't check hash settings.SearchDuplicatesCanUseFiletimes = true; results = SortFilesSearchDuplicates.Go(settings); settings.SearchDuplicatesCanUseFiletimes = false; expectedDuplicates = @"MTimeSmTextMNameNone.a|MTimeSmTextMNameNone.z|Same_Contents MTimeSmTextMNameOneOnLeft.a|MTimeSmTextMNameOneOnLeft.z|Same_Contents MTimeSmTextMNameOneOnRight.a|MTimeSmTextMNameOneOnRight.z|Same_Contents MTimeSmTextMNameOneOnRight.a|MTimeSmTextMNameOneOnRight.z_1|Same_Contents MTimeSmTextSmNameNone.a|MTimeSmTextSmNameNone.a|Same_Contents MTimeSmTextSmNameOneOnLeft.a|MTimeSmTextSmNameOneOnLeft.a|Same_Contents MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a|Same_Contents MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a_1|Same_Contents SmTimeAltTextSmNameNone.a|SmTimeAltTextSmNameNone.a|Same_Contents SmTimeAltTextSmNameOneOnLeft.a|SmTimeAltTextSmNameOneOnLeft.a|Same_Contents SmTimeAltTextSmNameOneOnRight.a|SmTimeAltTextSmNameOneOnRight.a|Same_Contents SmTimeSmTextMNameNone.a|SmTimeSmTextMNameNone.z|Same_Contents SmTimeSmTextMNameOneOnLeft.a|SmTimeSmTextMNameOneOnLeft.z|Same_Contents SmTimeSmTextMNameOneOnRight.a|SmTimeSmTextMNameOneOnRight.z|Same_Contents SmTimeSmTextMNameOneOnRight.a|SmTimeSmTextMNameOneOnRight.z_1|Same_Contents SmTimeSmTextSmNameNone.a|SmTimeSmTextSmNameNone.a|Same_Contents SmTimeSmTextSmNameOneOnLeft.a|SmTimeSmTextSmNameOneOnLeft.a|Same_Contents SmTimeSmTextSmNameOneOnRight.a|SmTimeSmTextSmNameOneOnRight.a|Same_Contents SmTimeSmTextSmNameOneOnRight.a|SmTimeSmTextSmNameOneOnRight.a_1|Same_Contents"; CompareResultsToString(results, expectedDuplicates); // search for differences in similar directories. results = SortFilesSearchDifferences.Go(settings); var expectedDifferences = @"|MTimeAddTextMNameNone.z|Right |MTimeAddTextMNameOneOnLeft.z|Right |MTimeAddTextMNameOneOnRight.z|Right |MTimeAddTextMNameOneOnRight.z_1|Right |MTimeAddTextSmNameOneOnRight.a_1|Right |MTimeAltTextMNameNone.z|Right |MTimeAltTextMNameOneOnLeft.z|Right |MTimeAltTextMNameOneOnRight.z|Right |MTimeAltTextMNameOneOnRight.z_1|Right |MTimeAltTextSmNameOneOnRight.a_1|Right |MTimeSmTextMNameNone.z|Right |MTimeSmTextMNameOneOnLeft.z|Right |MTimeSmTextMNameOneOnRight.z|Right |MTimeSmTextMNameOneOnRight.z_1|Right |MTimeSmTextSmNameOneOnRight.a_1|Right |SmTimeAddTextMNameNone.z|Right |SmTimeAddTextMNameOneOnLeft.z|Right |SmTimeAddTextMNameOneOnRight.z|Right |SmTimeAddTextMNameOneOnRight.z_1|Right |SmTimeAddTextSmNameOneOnRight.a_1|Right |SmTimeAltTextMNameNone.z|Right |SmTimeAltTextMNameOneOnLeft.z|Right |SmTimeAltTextMNameOneOnRight.z|Right |SmTimeAltTextMNameOneOnRight.z_1|Right |SmTimeAltTextSmNameOneOnRight.a_1|Right |SmTimeSmTextMNameNone.z|Right |SmTimeSmTextMNameOneOnLeft.z|Right |SmTimeSmTextMNameOneOnRight.z|Right |SmTimeSmTextMNameOneOnRight.z_1|Right |SmTimeSmTextSmNameOneOnRight.a_1|Right MTimeAddTextMNameNone.a||Left MTimeAddTextMNameOneOnLeft.a||Left MTimeAddTextMNameOneOnLeft.a_1||Left MTimeAddTextMNameOneOnRight.a||Left MTimeAddTextSmNameNone.a|MTimeAddTextSmNameNone.a|Changed MTimeAddTextSmNameOneOnLeft.a|MTimeAddTextSmNameOneOnLeft.a|Changed MTimeAddTextSmNameOneOnLeft.a_1||Left MTimeAddTextSmNameOneOnRight.a|MTimeAddTextSmNameOneOnRight.a|Changed MTimeAltTextMNameNone.a||Left MTimeAltTextMNameOneOnLeft.a||Left MTimeAltTextMNameOneOnLeft.a_1||Left MTimeAltTextMNameOneOnRight.a||Left MTimeAltTextSmNameNone.a|MTimeAltTextSmNameNone.a|Changed MTimeAltTextSmNameOneOnLeft.a|MTimeAltTextSmNameOneOnLeft.a|Changed MTimeAltTextSmNameOneOnLeft.a_1||Left MTimeAltTextSmNameOneOnRight.a|MTimeAltTextSmNameOneOnRight.a|Changed MTimeSmTextMNameNone.a||Left MTimeSmTextMNameOneOnLeft.a||Left MTimeSmTextMNameOneOnLeft.a_1||Left MTimeSmTextMNameOneOnRight.a||Left MTimeSmTextSmNameNone.a|MTimeSmTextSmNameNone.a|Changed MTimeSmTextSmNameOneOnLeft.a|MTimeSmTextSmNameOneOnLeft.a|Changed MTimeSmTextSmNameOneOnLeft.a_1||Left MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a|Changed SmTimeAddTextMNameNone.a||Left SmTimeAddTextMNameOneOnLeft.a||Left SmTimeAddTextMNameOneOnLeft.a_1||Left SmTimeAddTextMNameOneOnRight.a||Left SmTimeAddTextSmNameNone.a|SmTimeAddTextSmNameNone.a|Changed SmTimeAddTextSmNameOneOnLeft.a|SmTimeAddTextSmNameOneOnLeft.a|Changed SmTimeAddTextSmNameOneOnLeft.a_1||Left SmTimeAddTextSmNameOneOnRight.a|SmTimeAddTextSmNameOneOnRight.a|Changed SmTimeAltTextMNameNone.a||Left SmTimeAltTextMNameOneOnLeft.a||Left SmTimeAltTextMNameOneOnLeft.a_1||Left SmTimeAltTextMNameOneOnRight.a||Left SmTimeAltTextSmNameOneOnLeft.a_1||Left SmTimeSmTextMNameNone.a||Left SmTimeSmTextMNameOneOnLeft.a||Left SmTimeSmTextMNameOneOnLeft.a_1||Left SmTimeSmTextMNameOneOnRight.a||Left SmTimeSmTextSmNameOneOnLeft.a_1||Left"; CompareResultsToString(results, expectedDifferences); // account for all 96 files. // (SortFilesSearchDifferences doesn't check hashes, so although it knows // AddText are different because filesize changes, // it won't detect AltText unless filesize or lmt are also different.) var expectedSame = @"SmTimeAltTextSmNameNone.a|SmTimeAltTextSmNameNone.a SmTimeAltTextSmNameOneOnLeft.a|SmTimeAltTextSmNameOneOnLeft.a SmTimeAltTextSmNameOneOnRight.a|SmTimeAltTextSmNameOneOnRight.a SmTimeSmTextSmNameNone.a|SmTimeSmTextSmNameNone.a SmTimeSmTextSmNameOneOnLeft.a|SmTimeSmTextSmNameOneOnLeft.a SmTimeSmTextSmNameOneOnRight.a|SmTimeSmTextSmNameOneOnRight.a"; TestUtil.IsEq(filesCreated, CountFilenames(expectedDifferences) + CountFilenames(expectedSame)); // search for identical files with different write times // will find all with MTimeSmText var found = SortFilesSearchDuplicates.SearchForIdenticalFilesWithDifferentWriteTimes( settings.LeftDirectory, settings.RightDirectory, results); var expectedIdenticalContents = @"MTimeSmTextSmNameNone.a|MTimeSmTextSmNameNone.a|Changed MTimeSmTextSmNameOneOnLeft.a|MTimeSmTextSmNameOneOnLeft.a|Changed MTimeSmTextSmNameOneOnRight.a|MTimeSmTextSmNameOneOnRight.a|Changed"; CompareResultsToString(found, expectedIdenticalContents); }
static void TestMethod_AreTimesEqual() { var time = DateTime.Now; var timePlus3s = time.AddSeconds(3); var timePlus1hr = time.AddHours(1); // strict compare var settings = new SortFilesSettings(); settings.AllowFiletimesDifferForDST = false; settings.AllowFiletimesDifferForFAT = false; TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, time, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(time, timePlus3s, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(timePlus3s, time, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(time, timePlus1hr, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(timePlus1hr, time, settings)); // allow DST settings.AllowFiletimesDifferForDST = true; TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, time, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(time, timePlus3s, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(timePlus3s, time, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, timePlus1hr, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(timePlus1hr, time, settings)); // allow close settings.AllowFiletimesDifferForFAT = true; TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, time, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, timePlus3s, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(timePlus3s, time, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, timePlus1hr, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(timePlus1hr, time, settings)); // disallow DST settings.AllowFiletimesDifferForDST = false; TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, time, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(time, timePlus3s, settings)); TestUtil.IsEq(true, SortFilesSearchDifferences.AreTimesEqual(timePlus3s, time, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(time, timePlus1hr, settings)); TestUtil.IsEq(false, SortFilesSearchDifferences.AreTimesEqual(timePlus1hr, time, settings)); }