- Notifications
You must be signed in to change notification settings - Fork 89
Dev/yalyu/file save restore3 #113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| } | ||
| | ||
| [TestCleanup] | ||
| public void Cleanup() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for revert the libman.json file to its original status and also delete the libraries downloads during each test so as to not affect later tests. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you have to explain your code with a comment, then the code should be made more clear. I think you could just add a comment // Reset libman.json file contents
You also assume here that the undo stack will always work/be accurate. A better way to reset would be for TestInitialize to get the file content, and for Cleanup to set it back to the exact same content.
In reply to: 194349724 [](ancestors = 194349724)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That make sense, I will try using this way to revert the change in the file.
In reply to: 194549775 [](ancestors = 194549775,194349724)
| } | ||
| | ||
| [TestMethod] | ||
| public void FileSaveRestore_Cdnjs_DeleteLibrary() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FileSaveRestore_Cdnjs_DeleteLibrary() [](start = 20, length = 37)
Using another existing project with a ready libman.json can reduced the amount of Editor typing related code here. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could probably try getting content from the other json file as you point out for reverting file change.
In reply to: 194552391 [](ancestors = 194552391,194350175)
| | ||
| if(dir.Exists) | ||
| { | ||
| foreach(FileSystemInfo item in dir.EnumerateDirectories()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the same as Directory.EnumerateFileSystemEntries ? #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1.
Also, shouldn't this be recursive? Why do you limit to the top directory? You could just use Directory.EnumerateFileSystemEntries(path, "*", SearchOption.AllDirectories)
In reply to: 194396415 [](ancestors = 194396415)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
During the test design discussion, we are going to verify only top level items. If it's not too much work, I think verifying the sub-folder items also make sense to me. I will try using the enumeratefilesystem function.
In reply to: 194556684 [](ancestors = 194556684,194556460,194396415)
| { | ||
| string errorMessage = WaitForRestoredFilesHelper(cwd, new[] { expectedFileOrFolder }, caseInsensitive, timeout); | ||
| | ||
| if (errorMessage == null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is similar to the completion issue in that you appear to be waiting for a timeout for this method to pass #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be an different issue. Because the restoring is in progress after save the libman.json file. It needs sufficient time for restoring before we believe the unexpected file is not presented.
In reply to: 194397045 [](ancestors = 194397045)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ToddGrun left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🕐
| { | ||
| get | ||
| { | ||
| return _solutionRootPath; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_solutionRootPath [](start = 23, length = 17)
Can it just be auto-property instead of having a backing field?
public string SolutionRootPath { get; private set; } #Resolved There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| { | ||
| errorMessage = String.Concat(errorMessage, "\r\n*Didn't* fail when forcing completion with double timeout"); | ||
| } | ||
| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're going to do the "doubled timeout" thing in multiple places, it should be its own helper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For here. I use the doubled timeout for WaitForRestoredFile for file restore. But not using timeout for WaitForRestoredFileNotPresent because it is called after the WaitForRestore just verifying the not specified files are not included. So I think this doubled timeout can be written here.
In reply to: 194547985 [](ancestors = 194547985)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's now only used here for the waitforrestoredfiles.
In reply to: 194883862 [](ancestors = 194883862,194547985)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point is that we're copying the logic of retrying with an extra timeout duration from the completion helper method. Is this a pattern we want to do commonly? Then there should be a base waiter method to contain that retry logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. using a delagate waiter for both waitforrestoredfileshelper and waitfordeletedfileshelper function
In reply to: 195513255 [](ancestors = 195513255)
| { | ||
| public class LibmanTestsUtility | ||
| { | ||
| private static HashSet<string> GetTopLevelDirectoriesAndFiles(string cwd, bool caseInsensitive) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cwd [](start = 77, length = 3)
don't use abbreviated variable names #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return topLevelItems; | ||
| } | ||
| | ||
| public static void WaitForRestoredFiles(string cwd, IEnumerable<string> expectedFilesAndFolders, bool caseInsensitive, int timeout = 10000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cwd [](start = 55, length = 3)
don't use abbreviated variable names #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| public void initialize() | ||
| { | ||
| _webProject = Solution.ProjectsRecursive[_projectName]; | ||
| _libManConfig = _webProject.Find(SolutionItemFind.FileName, "libman.json"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Find(SolutionItemFind.FileName, "libman.json") [](start = 40, length = 46)
This should be in the project root, so use _webProject["libman.json"] #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| [TestInitialize()] | ||
| public void initialize() | ||
| { | ||
| _webProject = Solution.ProjectsRecursive[_projectName]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ProjectsRecursive [](start = 35, length = 17)
Is the project not in the root? Usually we do Solution[_projectName] #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The project folder will be in the root of the solution folder.
In reply to: 194548753 [](ancestors = 194548753)
| Editor.Caret.MoveToExpression("\"libraries\""); | ||
| Editor.Caret.MoveDown(2); | ||
| Editor.KeyboardCommands.Type("\"library\":"); | ||
| LibmanTestsUtility.WaitForCompletionEntry(Editor, "jquery", caseInsensitive: true, timeout: 5000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5000 [](start = 104, length = 4)
This is a really long timeout. Can we do something to make this shorter? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a little, because it takes time when first time we are trying to getting all library IDs from the server.
In reply to: 194550054 [](ancestors = 194550054)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get rid of this line as using new json file
In reply to: 194894203 [](ancestors = 194894203,194550054)
| public void FileSaveRestore_Unpkg_AddNewLibraryWithoutSpecifingFiles() | ||
| { | ||
| _libManConfig.Open(); | ||
| string[] expectedFilesAndFolders = new[] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expectedFilesAndFolders [](start = 21, length = 23)
Are you going to verify that there's anything inside of dist? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently not. Do you think we should verifying it for now?
In reply to: 194551666 [](ancestors = 194551666)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Editor.KeyboardCommands.Type("\"jquery.js\""); | ||
| | ||
| _libManConfig.Save(); | ||
| string cwd = Path.Combine(Path.GetDirectoryName(_webProject.FullPath), "wwwroot", "lib", "jquery"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cwd [](start = 19, length = 3)
don't abbreviate this name. I can't understand what it represents. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will change. This is current working directory I think. I follow the name pattern from otherwhere in libman.
In reply to: 194551848 [](ancestors = 194551848)
| Editor.KeyboardCommands.Type("\"files\": ["); | ||
| Editor.KeyboardCommands.Enter(); | ||
| Editor.KeyboardCommands.Type("\"LICENSE.txt\""); | ||
| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A much more realistic user scenarios (i.e. much more worth protecting with a test) would be to get the jquery.min.js file. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| for (int i = 0; i < 4; ++i) | ||
| { | ||
| Editor.Edit.DeleteLine(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DeleteLine takes a parameter for how many times to do it. You don't need a loop here. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like Editor.Edit.deleteLine doesn't accept parameter
In reply to: 194894785 [](ancestors = 194894785,194552547)
| Editor.KeyboardCommands.Type("\"library\":"); | ||
| LibmanTestsUtility.WaitForCompletionEntry(Editor, "jquery", caseInsensitive: true, timeout: 5000); | ||
| Editor.KeyboardCommands.Type("jquery@3.3.1"); | ||
| Editor.KeyboardCommands.Right(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need this line? Why can't we type something from jquery through the comma? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like there's a bug. If have comma in the line before, there will be two commas!
In reply to: 194552816 [](ancestors = 194552816)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| | ||
| _libManConfig.Save(); | ||
| LibmanTestsUtility.WaitForDeletedFiles(cwd, expectedFilesAndFolders, caseInsensitive: true); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this just check that there are no files left under the path? Instead of checking a hardcoded list? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For that matter, we should be deleting the folder too, but I can't remember if that fix is submitted yet.
In reply to: 194555302 [](ancestors = 194555302)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It make sense. I can try verifying there's no files in it
In reply to: 194555373 [](ancestors = 194555373,194555302)
jimmylewis left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🕐
| LibmanTestsUtility.WaitForRestoredFiles(cwd, expectedFilesAndFolders, caseInsensitive: true); | ||
| | ||
| Editor.Edit.DeleteToBeginningOfLine(); | ||
| _libManConfig.Save(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this leave a comma after "jquery.js", which invalidates the json file? I'm surprised this even works if the file doesn't parse. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like there's a bug make this comma work. However, I should not leave the extra comma here.
In reply to: 194557761 [](ancestors = 194557761)
jimmylewis left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about this PR some more, and it doesn't make sense to me that we're testing multiple providers separately, or even at all.
The Restore on Save functionality needs to verify that:
- A restore happens when the file is saved
- Any delta from the previous version of the libman.json file is cleaned up.
It does not need to test that individual providers are working, or that different file configurations are working. Those should be tested elsewhere.
| { | ||
| public class LibmanTestsUtility | ||
| { | ||
| private static HashSet<string> GetSubDirectoriesAndFiles(string currentWorkingDirectory, bool caseInsensitive) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private static HashSet GetSubDirectoriesAndFiles(string currentWorkingDirectory, bool caseInsensitive) [](start = 8, length = 110)
nit: I would probably implement this like the following
private static HashSet<string> GetSubDirectoriesAndFiles(string currentWorkingDirectory, bool caseInsensitive) { StringComparer comparer = caseInsensitive ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal; IEnumerable<string> subItems = Directory.EnumerateFileSystemEntries(currentWorkingDirectory, "*", SearchOption.AllDirectories); return new HashSet(subItems, comparer); } But it doesn't really bother me the other way. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Editor.KeyboardCommands.Type("wwwroot/lib/jquery-validate"); | ||
| Editor.Caret.MoveRight(); | ||
| Editor.KeyboardCommands.Type(","); | ||
| Editor.KeyboardCommands.Enter(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PathCompletionProvider will throw an exception if I combine it with "destination":
so currently I have to separate the comma to make the test work #Closed
| Path.Combine(pathToLibrary, "localization", "messages_ar.js"), | ||
| }; | ||
| | ||
| Editor.Caret.MoveToExpression("\"libraries\""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole block of typing - now you depend on the content generated above from being constant. Instead just replace the text buffer contents with the document you want:
string libmanContents = @"{ everything that goes in the file }"; Editor.Selection.SelectAll(); Editor.KeyboardCommands.Backspace(); Editor.Edit.InsertTextInBuffer(libmanContents); libmanConfig.Save(); #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should probably do this 3 times in this test:
- Save the original contents of the file for use in (3)
- Paste the file contents you want for the first library and verify.
- Paste the file contents you want for the changed file (added/removed libraries) and verify.
- Restore the original file contents from 0.
#Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And those 4 lines could be refactored into a method like ReplaceFileContents(string) #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| { | ||
| errorMessage = String.Concat(errorMessage, "\r\n*Didn't* fail when forcing completion with double timeout"); | ||
| } | ||
| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point is that we're copying the logic of retrying with an extra timeout duration from the completion helper method. Is this a pattern we want to do commonly? Then there should be a base waiter method to contain that retry logic.
| | ||
| namespace Microsoft.Web.LibraryManager.IntegrationTest | ||
| { | ||
| public class LibmanTestsUtility |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This utility class is just becoming a dumping ground for various helpers. Can you organize these to make them discoverable to new test authors in the future? This has been a significant compaint about test code on our team for a while, let's not repeat past mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal is to create a simpler API for discovering test utilities through the Helpers property, instead of having to reference static utilities.
| close this one as merged to preview 4 |
Adding file save restore tests for:
cdnjs and unpackage provider, including adding/deleting file/library.