// // Copyright 2014 Perforce Software Inc. // using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using Perforce.Helper; using Perforce.P4; using System.IO; using System.Collections.Generic; using Perforce; namespace Perforce_test { [TestClass] public class PerforceHelperTest { private static string serverUri = "localhost:1666"; private static string username = "bruno"; private static string password = "Brunopass"; private static string badPassword = "asdfsadfaf"; private static string dirPath = "//depot"; private static string filesPath = "//depot/Jam/MAIN/src"; private static string viewDepotPath = "//depot/Jam/MAIN/..."; private static string editFileDepotPath = "//depot/Jam/MAIN/src/command.c"; private static string graphicFileDepotPath = "//depot/www/dev/images/jamgraph-jam.gif"; private static string fileHistoryDepotPath = "//depot/Jam/REL2.1/src/headers.c"; private static string rollbackDepotPath = "//depot/Jam/MAIN/src/lists.c"; private static string clientName = "TEST_CLIENT"; private static string clientDescription = "Client created for test harness"; private static string clientRoot = @"c:\ws\TEST_CLIENT"; private static string clientFileBase = clientRoot + @"\depot\Jam\MAIN\src\"; private static string editFileClientPath = clientFileBase + "command.c"; private PerforceHelper helper; public TestContext TestContext { get; set; } [TestInitialize] public void Setup() { Console.WriteLine("### Setup()"); helper = new PerforceHelper(serverUri, username); if (TestContext.Properties.Contains("init")) { var initValue = (string) TestContext.Properties["init"]; if (initValue.Contains("login")) { Console.WriteLine("--- setup: logging in"); helper.Login(password); } if (initValue.Contains("client")) { Console.WriteLine("--- setup: creating client"); var client = helper.CreateClient(clientName, clientRoot, clientDescription); } if (initValue.Contains("mapping")) { Console.WriteLine("--- setup: creating client mapping"); helper.IncludeInClient(viewDepotPath); } } Console.WriteLine("### TEST: " + TestContext.TestName); } [TestMethod] public void T001_ConnectionTest() { Console.WriteLine("--- trying to connect"); Assert.IsTrue(helper.Connect()); Console.WriteLine("--- checking connection"); Assert.IsTrue(helper.IsConnected()); } [TestMethod] public void T002_ServerTimeTest() { var currentTime = Utility.GetEpochTime(); Console.WriteLine("EPOCH TIME: {0}", currentTime); var datetime = helper.GetServerTime(); Console.WriteLine(datetime); } [TestMethod] public void T004_LoginTest() { Console.WriteLine("--- logging out to begin test"); helper.Logout(); Console.WriteLine("--- checking with bad password"); Assert.IsFalse(helper.Login(badPassword).Item1); Assert.IsFalse(helper.IsLoggedIn()); Console.WriteLine("--- checking with valid password"); Assert.IsTrue(helper.Login(password).Item1); Assert.IsTrue(helper.IsLoggedIn()); } [TestMethod] [TestProperty("init", "login")] public void T006_GetKeyTest() { var key = "p4search.url"; var result = helper.GetKey(key); Console.WriteLine("{0} = {1}", key, result); } [TestMethod] [TestProperty("init", "login")] public void T100_ListDepotsTest() { Console.WriteLine("--- getting list of local depots"); var depots = helper.ListDepots(true); Assert.IsNotNull(depots); foreach (var d in depots) { Console.WriteLine(d.Id); } } [TestMethod] [TestProperty("init", "login")] public void T101_ListDirectoriesTest() { Console.WriteLine("--- getting list of directories in {0}", dirPath); var dirs = helper.ListDirectories(dirPath); foreach (var d in dirs) { Console.WriteLine(d); } Console.WriteLine("dirPath = " + dirPath); } [TestMethod] [TestProperty("init", "login")] public void T102_ListFilesTest() { var fileMetadataList = helper.ListFiles(filesPath + "/*"); Console.WriteLine("--- listing files on path"); foreach (var md in fileMetadataList) { Console.WriteLine(md.GetFileName()); } } [TestMethod] [TestProperty("init", "login")] public void T103_ListClientsTest() { var clientList = helper.ListClients(); Console.WriteLine("--- listing all clients owned by {0}", username); foreach (var c in clientList) { Console.WriteLine(c.Name); } } [TestMethod] [TestProperty("init", "login")] public void T104_CreateClientTest() { Console.WriteLine("--- creating a client {0}", clientName); var client = helper.CreateClient(clientName, clientRoot, clientDescription); Assert.IsTrue(helper.ClientExists(clientName)); } [TestMethod] [TestProperty("init", "login,client")] public void T105_IncludeInClientTest() { var client = helper.IncludeInClient(viewDepotPath); var entry = helper.CreateMapEntry(viewDepotPath, client.Name, MapType.Include); Assert.IsTrue(client.ViewMap.Contains(entry)); } [TestMethod] [TestProperty("init", "login,client")] public void T106_RemoveFromClientTest() { var client = helper.RemoveFromClient(viewDepotPath); if(client != null && client.ViewMap != null) { var entry = helper.CreateMapEntry(viewDepotPath, client.Name, MapType.Include); Assert.IsFalse(client.ViewMap.Contains(entry)); } } [TestMethod] [TestProperty("init", "login,client")] public void T108_CreateChangelistTest() { Console.WriteLine("--- creating a new changelist"); var change = helper.CreateChangelist("a test changelist"); Console.WriteLine("--- checking to see if changelist {0} is pending", change.Id); Assert.IsTrue(change.Pending); Console.WriteLine("--- retrieving the changelist from Perforce"); var change2 = helper.GetChangelist(change.Id); Assert.AreEqual(change2.Id, change.Id); Console.WriteLine("--- deleting the pending changelist"); helper.DeleteChangelist(change.Id); } [TestMethod] [TestProperty("init", "login,client")] public void T109_GetCurrentPendingChangelistTest() { var change = helper.CreateChangelist("a test pending changelist"); Console.WriteLine("--- trying to get the current pending changelist"); var change2 = helper.GetCurrentPendingChangelist(); Console.WriteLine("--- testing to verify that changelist was retrieved"); Assert.IsNotNull(change2); Console.WriteLine("Current pending changelist is {0}", change2.Id); } [TestMethod] [TestProperty("init", "login,client")] public void T110_GetChangelists() { var changes = helper.ListChanges(filesPath); foreach (var c in changes) { Console.WriteLine("--- {0}", c.Id); } } [TestMethod] [TestProperty("init", "login,client")] public void T112_GetAllPendingChangelists() { var c1 = helper.CreateChangelist("test change1"); var c2 = helper.CreateChangelist("test change2"); var changelists = helper.GetAllPendingChangelists(); Assert.AreEqual(2, changelists.Count); helper.DeleteChangelist(c1); helper.DeleteChangelist(c2); } [TestMethod] [TestProperty("init", "login,client")] public void T200_SyncWorkspaceFilesTest() { var files = helper.SyncWorkspaceFiles(force:true); if (files != null) { Console.WriteLine("--- sync results:"); foreach (var f in files) { Console.WriteLine(f.DepotPath); } } else { Console.WriteLine("--- no files need synchronization"); } } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T201_GetFileMetaDataTest() { var paths = new List<string>(); paths.Add(editFileDepotPath); paths.Add(editFileClientPath); var results = helper.GetFileMetaData(paths); foreach (var md in results) { Console.WriteLine(md.DepotPath.Path); } Console.WriteLine("-- testing metadata for new file"); var f = createRandomFile(clientFileBase); var md2 = helper.GetFileMetaData(f); Assert.IsNull(md2); helper.MarkFileForAdd(f); md2 = helper.GetFileMetaData(f); Assert.IsNotNull(md2); Console.WriteLine(md2.DepotPath.Path); var change = helper.GetCurrentPendingChangelist(); helper.RevertChangelist(change); helper.DeleteChangelist(change); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T203_GetFilesModifiedSinceTest() { var serverTime = helper.GetServerTime(); Console.WriteLine("SERVER TIME: {0}", serverTime); var files = helper.ListFiles("//...", showDeleted: true, sinceTime: serverTime); Assert.IsNull(files); var f = createRandomFile(clientFileBase); helper.MarkFileForAdd(f); helper.SubmitChangelist(); files = helper.ListFiles("//...", showDeleted: true, sinceTime: serverTime); Assert.AreEqual(1, files.Count); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T204_MoveFilesToNewChangelistTest() { helper.RevertFiles(serverOnly: false, paths: "//..."); helper.SyncWorkspaceFiles(); var editList = helper.CheckoutFiles(false, filesPath + "/..."); var count = editList.Count; var currentChange = helper.GetCurrentPendingChangelist(); Console.WriteLine("--- current changelist has {0} files", currentChange.Files.Count); Assert.AreEqual(count, currentChange.Files.Count); var newChange = helper.CreateChangelist("a TEST changelist"); Assert.AreEqual(0, newChange.Files.Count); var files = new List<string>(); files.Add(editFileDepotPath); Console.WriteLine("--- moving files to changelist {0}", newChange.Id); helper.MoveFilesToNewChangelist(files, newChange.Id); currentChange = helper.GetChangelist(currentChange.Id); Console.WriteLine("--- changelist now has {0} files", currentChange.Files.Count); Assert.AreEqual(count - 1, currentChange.Files.Count); newChange = helper.GetChangelist(newChange.Id); Assert.AreEqual(1, newChange.Files.Count); // CLEAN UP helper.RevertChangelist(currentChange); helper.DeleteChangelist(currentChange); helper.RevertChangelist(newChange); helper.DeleteChangelist(newChange); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T210_AddFileTest() { var f = createRandomFile(clientFileBase); helper.MarkFileForAdd(f); var list = helper.GetChangelistFiles(); foreach (var item in list) { Console.WriteLine(item.DepotPath.Path); } helper.SubmitChangelist(); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T220_EditFileTest() { var files = helper.CheckoutFiles(false, editFileDepotPath); if (files != null) { foreach (var f in files) { Console.WriteLine(f); appendTextToFile(f.LocalPath.Path); } helper.SubmitChangelist(); } } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T222_DeleteFilesTest() { var f = createRandomFile(clientFileBase); Console.WriteLine("-- Created file: {0}", f); helper.MarkFileForAdd(f); helper.SubmitChangelist(); Console.WriteLine("-- Preparing to delete"); var results = helper.DeleteFiles(serverOnly:false, paths: f); foreach (var r in results) { Console.WriteLine("-- result: {0}", r.DepotPath.Path); } helper.SubmitChangelist(); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T224_RenameFileTest() { var f = createRandomFile(clientFileBase); Console.WriteLine("-- Source file: {0}", f); helper.MarkFileForAdd(f); helper.SubmitChangelist(); Console.WriteLine("-- added {0} to server", f); var fprime = getRandomFileName(clientFileBase); Console.WriteLine("-- Destination file: {0}", fprime); var results = helper.RenameFile(f, fprime); foreach (var r in results) { Console.WriteLine("-- result: {0}", r.DepotPath.Path); } var submitResults = helper.SubmitChangelist(); Console.WriteLine("-- submitted changelist @{0}", submitResults.Results.ChangeIdAfterSubmit); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T225_CopyFileTest() { var f1 = createRandomFile(clientFileBase); Console.WriteLine("-- Source file: {0}", f1); helper.MarkFileForAdd(f1); helper.SubmitChangelist(); var f2 = getRandomFileName(clientFileBase); helper.CopyFile(f1, f2); var submitResults = helper.SubmitChangelist(); Console.WriteLine("-- submitted changelist @{0}", submitResults.Results.ChangeIdAfterSubmit); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T226_GetFileHistoryTest() { var history = helper.GetFileHistory(fileHistoryDepotPath); foreach (var h in history) { Console.WriteLine("DepotPath: {0}", h.DepotPath.Path); Console.WriteLine("Revision: {0}", h.Revision); Console.WriteLine("Modified by: {0}", h.UserName); Console.WriteLine("Description: {0}", h.Description); Console.WriteLine("Checked in: {0}", h.Date); } } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T227_ShelveFileTest() { var f = createRandomFile(clientFileBase); Console.WriteLine("-- Source file: {0}", f); var specs = helper.MarkFileForAdd(f); Assert.AreEqual(1, specs.Count); var dp = specs[0].DepotPath.Path; Assert.IsFalse(helper.IsFileShelved(dp)); helper.ShelveFiles(dp); Assert.IsTrue(helper.IsFileShelved(dp)); var shelved = helper.GetShelvedChangelistFiles(); foreach (var s in shelved) { Console.WriteLine("-- {0}", s.Path.Path); } var results = helper.DeleteShelvedFiles(paths: "//..."); shelved = helper.GetShelvedChangelistFiles(); Assert.IsNull(shelved); helper.RevertFiles(serverOnly: true, paths: "//..."); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T228_ReconcileFileTest() { var f = createRandomFile(clientFileBase); var result = helper.ReconcileFiles(f); Console.WriteLine(result); helper.SubmitChangelist(); System.IO.File.SetAttributes(f, FileAttributes.Normal); System.IO.File.Delete(f); result = helper.ReconcileFiles(f); Console.WriteLine(result); } [TestMethod] [TestProperty("init", "login")] public void T230_GetFileFromServerTest() { var filename = helper.GetFileFromServer(graphicFileDepotPath); Console.WriteLine(filename); } [TestMethod] [TestProperty("init", "login")] public void T231_GetDirectoryFromServerTest() { var dir = @"c:\temp\junk"; Directory.CreateDirectory(dir); var results = helper.GetDirectoryFromServer(filesPath, dir); Console.WriteLine(results); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T232_GetFileFromShelfTest() { var f = createRandomFile(clientFileBase); Console.WriteLine("-- Source file: {0}", f); var specs = helper.MarkFileForAdd(f); var depotPath = specs[0].DepotPath.Path; Console.WriteLine("-- Depot path: {0}", depotPath); var shelvedFiles = helper.ShelveFiles(f); Assert.IsTrue(helper.IsFileShelved(depotPath)); var change = helper.GetOrCreatePendingChangelist(); Console.WriteLine("-- Change id: {0}", change.Id); helper.RevertFiles(serverOnly: false, paths: f); var downloaded = helper.GetFileFromShelf(depotPath); } [TestMethod] [TestProperty("init", "login,client")] public void T235_GetPathSizesTest() { var sizes = helper.GetPathSizes(viewDepotPath); Console.WriteLine("{0} {1} files {2} kb", sizes.Path, sizes.FileCount, sizes.FileSize/1024); } [TestMethod] [TestProperty("init", "login,client")] public void T240_IsDirectoryMappedTest() { var path = "//depot/MapTest"; helper.IncludeInClient(path + "/..."); var result = helper.IsDirectoryMapped(path); Assert.IsTrue(result); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T250_RollbackFileToRevisionTest() { helper.SyncWorkspaceFiles(); var md = helper.GetFileMetaData(rollbackDepotPath); Console.WriteLine("HEAD REV: {0}", md.HeadRev); var fileSpecs = helper.CheckoutFiles(serverOnly: false, paths: rollbackDepotPath); var localFile = fileSpecs[0].LocalPath; appendTextToFile(localFile.Path); helper.SubmitChangelist(); md = helper.GetFileMetaData(rollbackDepotPath); Console.WriteLine("HEAD REV: {0}", md.HeadRev); helper.RollbackFileToRevision(rollbackDepotPath, 3); md = helper.GetFileMetaData(rollbackDepotPath); Console.WriteLine("HEAD REV: {0}", md.HeadRev); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T251_RollbackFolderToChangelistTest() { helper.SyncWorkspaceFiles(); var path = "//depot/Jam/MAIN/src"; var changeId = 320; var results = helper.RollbackFolderToChangelist(path, changeId); } [TestMethod] [TestProperty("init", "login,client,mapping")] public void T260_SubmitFileTest() { var f = createRandomFile(clientFileBase); Console.WriteLine("-- Created file: {0}", f); var addResults = helper.MarkFileForAdd(f); Assert.AreEqual(addResults.Count, 1); var depotFile = addResults[0].DepotPath.Path; Console.WriteLine("-- depot file: {0}", depotFile); var submitResults = helper.SubmitSingleFile(depotFile, "TEST: SubmitFileTest()"); Console.WriteLine("-- change {0} submitted", submitResults.Results.ChangeIdAfterSubmit); } [TestMethod] [TestProperty("init", "login,client")] public void T998_DeleteClientTest() { Console.WriteLine("--- deleting pending changelist"); helper.DeletePendingChangeList(); Console.WriteLine("--- removing the client {0}", clientName); helper.DeleteClient(clientName); Assert.IsFalse(helper.ClientExists(clientName)); } [TestMethod] public void T999_LogoutTest() { Console.WriteLine("--- logging out"); Assert.IsTrue(helper.Logout()); Assert.IsFalse(helper.IsLoggedIn()); } [TestCleanup] public void Teardown() { Console.WriteLine("### Teardown()"); } // helper methods private string createRandomFile(string baseDir) { var fileName = getRandomFileName(baseDir); byte[] data = new byte[8192]; Random rng = new Random(); using (FileStream stream = System.IO.File.OpenWrite(fileName)) { for (int i = 0; i < 8; i++) { rng.NextBytes(data); stream.Write(data, 0, data.Length); } } return fileName; } private string getRandomFileName(string baseDir) { var rndName = Path.GetRandomFileName(); var fileName = baseDir + rndName; return fileName; } private void appendTextToFile(string file) { var random = new Random(); var numlines = random.Next(10)+1; using (StreamWriter sw = System.IO.File.AppendText(file)) { for (var i = 0; i < numlines; i++) { sw.WriteLine(generateRandomString()); } } } private string generateRandomString() { var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var stringChars = new char[8]; var random = new Random(); for (int i = 0; i < stringChars.Length; i++) { stringChars[i] = chars[random.Next(chars.Length)]; } return new String(stringChars); } } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 15071 | alan_petersen |
Populate -o //guest/perforce_software/piper/... //guest/alan_petersen/piper/.... |
||
//guest/perforce_software/piper/windows/main/Perforce-test/PerforceHelperTest.cs | |||||
#2 | 13571 | alan_petersen | Lots 'o bug fixes | ||
#1 | 11255 | alan_petersen | Rename/move file(s) | ||
//guest/perforce_software/piper/windows/Perforce-test/PerforceHelperTest.cs | |||||
#3 | 11032 | alan_petersen |
MEGA UPDATE: - fixed bug in folder rollback was failing due to deleted files - files needed to be re-added with the downgrade (-d) flag - put some checking in to stop/start the background workers when - folder versioning - can select 'show versions' on mapped folders - currently limites the number of changelists displayed to the last 50 - rollback button is disabled/hidden unless there are no files in the path (//path/to/folder/...) that are opened (uses p4 opened -a path) - various fixes for some strange null pointer exceptions - fixed folder items (edit all/revert all) - needs some testing to ensure that it is functioning correctly (e.g. when there are locked files in the path being checked out) - general code clean-up -- primarily using the Utility method to obtain the PerforceHelper, rather than having to cast all the time. - found some stability issues (at least when communicating with a local p4d running in the same virtual machine) so some additional error checking/handling was added - reconcile files action now provides feedback via a wait dialog: while reconcile is running, the dialog is displayed along with a wait indicator, when complete a message is displayed that the reconcile is finished - submit changes - submit now perfomed within a wait dialog: dialog displays message along with a wait indicator, results of the submit are displayed when complete - currently, the 'ok' button is disabled until the submit completes. - looking into providing a progress bar (using the feedback mechanism in the API) to provide some more interesting information (and to give users the sense that something is actually happening when a large changelist is begin submitted) - added copy function to PerforceHelper along with test case - implemented copy (ctrl-c) and paste (ctrl-v) in DESI - limitations: - currently only implemented for FILES (not folders) - to paste, one must select the destination FOLDER - next steps: - get working for folders - implement cut (ctrl-x) - permit paste into a column (more intuitive) - rebuilt using 'Any CPU' target -- not sure if this will fix the error seen by the Win7-64 user -- we may need to switch to separate 32- and 64-bit builds - fixed defect #78: delete and move/delete files are no longer displayed in the server view - fixed defect #76: tags now displayed in version history - added MemoryCache for repository reference -- the repository reference was getting stale and creating strange errors, so a reference is now stored in the MemoryCache with a SlidingExpiration of 2 minutes. - fixes #80: copy checks out file -- remnant of code from the rename logic was checking out the code - fixes #14: mail now opens outlook using office API - fixes #72: submit dialog now waits for results from submit, and if there is an error the error message is displayed, otherwise the changelist number is displayed - fixes #75: folder versioning changes -- restore version button now always displayed, but not connected to anything if the folder has opened items; -- opened items now ignored items marked for Add -- this could result in the folder being re-created if/when the user submits the added files - fixed bug in submit dialog in which changelist number was not displayed correctly - fixed bug in submission of partial changelists -- files moved to new changelist but original not updated, resulting in error - #79 - add file now works correctly, relying on the client path rather than the //dummy_depot_path #41: various changes and refactoring to support 'Recent' view - background sync causes immediate refresh of the recent list - ability to mark items as 'read' -- removed from the recent list and the view is refreshed #43 - udpates to logic to deal with transient threading issues (causing the NoSuchObject exceptions) and sync/refresh of workspace files to added files. #48: submit single file now working -- when submit file is selected, the file is moved to a shiny new changelist, and that changelist is presented in the UI - refactoring of submit pane logic to allow passing in a changelist ID incremental build with partially working toolbar buttons -- still working on the forward/back buttons (they aren't quite working right yet) - toolbar items are now functional: left/right nav, add files, create folder addresses #12: favorite folders -- added favorite folder functionality to the application - favorites are now stored in a workspace-specific property (client_name.favoriteFolders) in the favorites.json file in the user's configuration directory (this file is created if it does not exist) - favorites can be edited by double-clicking on the label, right-clicking the label and selecting 'edit', or clicking on the edit icon - favorites can be deleted by right-clicking on the label and selecting 'delete' update involved various refactoring so enable the hidden 'Favorites' selector and select the appropriate sidebar selector (Workspace or Server) when the favorite is selected - favorite tags implemented, satisfying ticket #18 - favorite tags are stored in a workspace-specific property (client_name.favoriteTags) in the favorites.json file in the user's configuration directory (this file is created if it does not exist) - favorite tags can be added by clicking on the '+' that appears when hovering over the Favorite Tags header in the sidebar - a popup appears with a textfield - ESC cancels the add and closes the popup - Enter or clicking on the add button adds the tag to the property (immediately saved) and updates the Favorite Tags sidebar list and closes the popup - changing focus (ie clicking somewhere else in the application) cancels the add and closes the popup - favorite tags can be selected/deselected with a single click - selected tags have a checkmark in the rightmost column - favorite tags can be deleted by right-clicking on the label and selecting 'delete' - list items in ColumnDisplay.xaml modified - FileItem model class modified with boolean method to determine if the file has a selected tag (matching is case insensitive) - FavoritesHelper caches selected tags (to avoid unnecessary IO and parsing) - FavoriteTagItem modified to - fixing copy/paste functionality: - copy/paste now uses filesystem copy and paste (rather than p4 copy) - CopyDirectory method added to Utility class to assist in copying of entire directory structures - copy enabled from either the server tab or the workspace tab... paste only allowed on the workspace tab - wait dialog implemented for the paste process -- should happen quickly if copy is on local filesystem, but if copy is from the server then copy may take a while if the file(s) being copied are large (they have to be downloaded first) - confirmation dialog when folders selected for the copy (giving user the option of skipping large directories if they were selected accidentally) - implementation of p4 sizes code to determine size/number of files in a given path - implementation of p4 print for a depot path -- by default saves to a temp directory, but in the case of copy/paste the print is performed directly to the target directory Addresses DEFECT #91 -- Desi crashing on viewing old versions - previous refactoring had introduced the VersionItem model class, but there were still some remnants of references to FileHistory around, causing issues (ie. crashing) - changelist cleanup had used the -f (force) flag, which hadn't appeared as an issue because the test cases currently run as an admin user, but that masked the fact that only admins can do 'p4 change -d -f'. Doh #94 DEFECT: Selecting tags causes error in Server view - issue was due to tag attributes not retrieved in HEX format, so hex decoding then failed (because they weren't hex!) - this is now fixed in the PerforceHelper - general code cleanup and optimization - helper methods in the utility class to retrieve common objects from the App context - start sync now first checks the preferences to ensure that sync is actually turned on - background processes now wait for initial workspace selection before starting up #36: DEFECT: Refresh color coding - modifications for #88 fix this too #52: DEFECT: Cannot move files from "My Pending Changes" to "Trash" - modified CommandHelper logic to revert files that are in any state other than 'None' when trying to delete #88: DEFECT: icon should be different for items not on server - logic to determine file status updated - icon sizes bumped up slightly (from 18px to 24px) to make differences more visible.. #96: DEFECT: Adding files double window - this was due to a bug in the AddFilesButton_Click method of ToolBar.xaml.cs... basically ShowDialog() was called twice! DOH!! #99: DEFECT: Refresh color coding - modified logic around refreshing after a paste, seems to have fixed this issue #106: DEFECT: Paste a file in a folder where the name exists and the application crashes - added CopyFileToDirectory method to utility class to check to see if the destination file already exists... if it does, then (Copy) is appended to the filename - if there is already a file named xxx (Copy), then a counter is appended: xxx (Copy 2) - this is repeated until it comes up with a filename that doesn't conflict #104: DEFECT: right click option to open file as read only does not work - Code in ContextMenuHelper's ViewWorkspaceFile method was not wired to the code that opens a file. Now it is! - no specific bugs fixed, just trying to get refresh to be a little more responsive and context menus working a little better - reworked DelegateCommand to permit parameter - reworked various menuitem commands to include item(s) selected as parameters - reworked command methods to get parameter, cast it appropriately to the item(s), perform the operation(s), and then refresh the items as well as associated UI components - reworked some methods in MainWindow to take item(s) as arguments (rather than just trying to get the currently selected item -- sometimes when you right-click on something it isn't fully selected) #107: Defect: Unsync from computer not working - modified code that syncs/unsyncs to refresh items after change -- should make for a more responsive interface - modified PerforceHelper code that sets the client to ensure that rmdir is set as an option - fixed Exit menu item to actually shut down the application (YAY) #49: Defect: Desi throws exception when internet connection is lost - modified the GetPerforceHelper utility method to check for a live server. If the server is unreachable, the user is presented with the option to relaunch the application or shutdown #97: DEFECT: Object error when using navigation buttons - code was checking Perforce server to determine if a path was a directory or file, but when the file was newly created it doesn't exist on the server so it returned false, which later caused a null pointer exception. The PerforceHelper IsDirectory code was modified to check, as a last restort, the client path to see if the file is a directory using System.IO.Directory.exists() - modification to MainWindow.cs to re-enable the filesystem watcher #73: Defect: Checkout and delete file .. appropriate change in status not done - code in filesystem watcher was not handing deletes of opened files correctly... opened files need to be reverted first, then they can be deleted using a p4 delete. Since the file no longer exists on the filesystem, these p4 commands are performed as server-only (-k option). When the file is an Add or MoveAdd, then the server-side revert is just performed. Otherwise, if the file is in any other state (other than none), a server-side revert is performed, then the server-side delete. #92: Defect: Option for unshelving missing - added a button to the file info screen for unshelving. Since unshelving may overwrite changes the user has made, a dialog is presented and the user must confirm the unshelve operation. - application now opens with window displaying the file/folder in question when given a command-line argument in the form p4://... |
||
#2 | 10804 | alan_petersen |
UPDATE: - some code cleanup - submit now catches errors more intelligently and displays them - connection failures in background processes now display dialog indicating connection failure - this stops the background process (this will avoid the endless dialog boxes seen in the Mac version!) - currently, dismissing the dialog exits the application -- this may change once I get the 'change connection' feature working |
||
#1 | 10761 | alan_petersen |
initial drop of Piper for Windows.... this version still has _many_ bugs (er... i mean "unintended features") but I will be updating it over the next week as more stability is added. |