From e55297ba7fbcb1a00f31d0ddd21e022062578c0e Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 9 Sep 2016 15:06:27 -0700 Subject: [PATCH 1/3] Remove Node Code Snippets in Favor of Typescript **Bug** Now that our Node.js editor has been replaced with TypeScript, users can no longer access code snippets. This was already the case when using ES6 IntelliSense **Fix** Code snippet functionality will now be provided by TypeScript: https://github.com/Microsoft/TypeScript/issues/312 This change removes the code snippets themselves from our code. --- .../Nodejs/Intellisense/ExpansionClient.cs | 3 - .../Intellisense/IntellisenseController.cs | 34 - Nodejs/Product/Nodejs/Nodejs.csproj | 114 --- Nodejs/Product/Nodejs/NodejsPackage.cs | 2 - .../Nodejs/Snippets/1033/Nodejs/cl.snippet | 26 - .../Snippets/1033/Nodejs/dowhile.snippet | 32 - .../Nodejs/Snippets/1033/Nodejs/else.snippet | 25 - .../1033/Nodejs/express_delete.snippet | 33 - .../Snippets/1033/Nodejs/express_get.snippet | 33 - .../Snippets/1033/Nodejs/express_post.snippet | 33 - .../Snippets/1033/Nodejs/express_put.snippet | 33 - .../Nodejs/Snippets/1033/Nodejs/for.snippet | 34 - .../Nodejs/Snippets/1033/Nodejs/forin.snippet | 34 - .../Snippets/1033/Nodejs/forprops.snippet | 36 - .../Nodejs/Snippets/1033/Nodejs/forr.snippet | 34 - .../Snippets/1033/Nodejs/function.snippet | 30 - .../Nodejs/Snippets/1033/Nodejs/if.snippet | 30 - .../Nodejs/Snippets/1033/Nodejs/iife.snippet | 30 - .../Nodejs/Snippets/1033/Nodejs/parse.snippet | 26 - .../Snippets/1033/Nodejs/readfile.snippet | 34 - .../Snippets/1033/Nodejs/readstream.snippet | 33 - .../Snippets/1033/Nodejs/require.snippet | 26 - .../Snippets/1033/Nodejs/server.snippet | 33 - .../Snippets/1033/Nodejs/stringify.snippet | 26 - .../Snippets/1033/Nodejs/switch.snippet | 29 - .../Nodejs/Snippets/1033/Nodejs/try.snippet | 32 - .../Nodejs/Snippets/1033/Nodejs/tryf.snippet | 34 - .../Nodejs/Snippets/1033/Nodejs/while.snippet | 30 - .../Nodejs/Snippets/1033/Nodejs/with.snippet | 30 - .../Nodejs/Snippets/1033/SnippetsIndex.xml | 19 - .../Snippets/1033/Test/describe.snippet | 31 - .../Nodejs/Snippets/1033/Test/it.snippet | 31 - Nodejs/Tests/Core.UI/Nodejs.Tests.UI.csproj | 2 - Nodejs/Tests/Core.UI/ProjectTests.cs | 915 ------------------ Nodejs/Tests/Core.UI/SnippetsTests.cs | 347 ------- 35 files changed, 2274 deletions(-) delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/cl.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/dowhile.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/else.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_delete.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_get.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_post.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_put.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/for.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forin.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forprops.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forr.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/function.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/if.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/iife.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/parse.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/readfile.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/readstream.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/require.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/server.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/stringify.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/switch.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/try.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/tryf.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/while.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Nodejs/with.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/SnippetsIndex.xml delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Test/describe.snippet delete mode 100644 Nodejs/Product/Nodejs/Snippets/1033/Test/it.snippet delete mode 100644 Nodejs/Tests/Core.UI/ProjectTests.cs delete mode 100644 Nodejs/Tests/Core.UI/SnippetsTests.cs diff --git a/Nodejs/Product/Nodejs/Intellisense/ExpansionClient.cs b/Nodejs/Product/Nodejs/Intellisense/ExpansionClient.cs index 9504592e3..4be8a7180 100644 --- a/Nodejs/Product/Nodejs/Intellisense/ExpansionClient.cs +++ b/Nodejs/Product/Nodejs/Intellisense/ExpansionClient.cs @@ -36,9 +36,6 @@ internal sealed class ExpansionClient : IVsExpansionClient { private bool _sessionEnded, _selectEndSpan; private ITrackingPoint _selectionStart, _selectionEnd; - public const string SurroundsWith = "SurroundsWith"; - public const string Expansion = "Expansion"; - public ExpansionClient(ITextView textView, IVsEditorAdaptersFactoryService adapterFactory, IServiceProvider serviceProvider) { _textView = textView; _serviceProvider = serviceProvider; diff --git a/Nodejs/Product/Nodejs/Intellisense/IntellisenseController.cs b/Nodejs/Product/Nodejs/Intellisense/IntellisenseController.cs index 8848361ea..312944830 100644 --- a/Nodejs/Product/Nodejs/Intellisense/IntellisenseController.cs +++ b/Nodejs/Product/Nodejs/Intellisense/IntellisenseController.cs @@ -49,8 +49,6 @@ internal sealed class IntellisenseController : IIntellisenseController, IOleComm private IQuickInfoSession _quickInfoSession; private IOleCommandTarget _oldTarget; private IEditorOperations _editOps; - private static string[] _allStandardSnippetTypes = { ExpansionClient.Expansion, ExpansionClient.SurroundsWith }; - private static string[] _surroundsWithSnippetTypes = { ExpansionClient.SurroundsWith }; [ThreadStatic] internal static bool ForceCompletions; @@ -636,10 +634,6 @@ public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pv return VSConstants.S_OK; } break; - case VSConstants.VSStd2KCmdID.SURROUNDWITH: - case VSConstants.VSStd2KCmdID.INSERTSNIPPET: - TriggerSnippet(nCmdID); - return VSConstants.S_OK; case VSConstants.VSStd2KCmdID.SHOWMEMBERLIST: case VSConstants.VSStd2KCmdID.COMPLETEWORD: ForceCompletions = true; @@ -654,34 +648,6 @@ public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pv return _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); } - private void TriggerSnippet(uint nCmdID) { - if (_expansionMgr != null) { - string prompt; - string[] snippetTypes; - if ((VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.SURROUNDWITH) { - prompt = SR.GetString(SR.SurroundWith); - snippetTypes = _surroundsWithSnippetTypes; - } else { - prompt = SR.GetString(SR.InsertSnippet); - snippetTypes = _allStandardSnippetTypes; - } - - _expansionMgr.InvokeInsertionUI( - GetViewAdapter(), - _expansionClient, - Guids.NodejsLanguageInfo, - snippetTypes, - snippetTypes.Length, - 0, - null, - 0, - 0, - prompt, - ">" - ); - } - } - private bool TryTriggerExpansion() { if (_expansionMgr != null) { var snapshot = _textView.TextBuffer.CurrentSnapshot; diff --git a/Nodejs/Product/Nodejs/Nodejs.csproj b/Nodejs/Product/Nodejs/Nodejs.csproj index d70324fef..026acb30d 100644 --- a/Nodejs/Product/Nodejs/Nodejs.csproj +++ b/Nodejs/Product/Nodejs/Nodejs.csproj @@ -768,115 +768,6 @@ - - PreserveNewest - true - Designer - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - Always - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - - - PreserveNewest - true - @@ -907,11 +798,6 @@ true RemoteDebug - - Designer - PreserveNewest - true - PreserveNewest true diff --git a/Nodejs/Product/Nodejs/NodejsPackage.cs b/Nodejs/Product/Nodejs/NodejsPackage.cs index afbb786fa..e6797ca61 100644 --- a/Nodejs/Product/Nodejs/NodejsPackage.cs +++ b/Nodejs/Product/Nodejs/NodejsPackage.cs @@ -93,8 +93,6 @@ namespace Microsoft.NodejsTools { [ProvideLanguageEditorOptionPage(typeof(NodejsIntellisenseOptionsPage), NodejsConstants.Nodejs, "IntelliSense", "", "3048")] #endif [ProvideLanguageEditorOptionPage(typeof(NodejsAdvancedEditorOptionsPage), NodejsConstants.Nodejs, "Advanced", "", "3050")] - [ProvideCodeExpansions(Guids.NodejsLanguageInfoString, false, 106, "Nodejs", @"Snippets\%LCID%\SnippetsIndex.xml", @"Snippets\%LCID%\Nodejs\")] - [ProvideCodeExpansionPath("Nodejs", "Test", @"Snippets\%LCID%\Test\")] internal sealed partial class NodejsPackage : CommonPackage { internal const string NodeExpressionEvaluatorGuid = "{F16F2A71-1C45-4BAB-BECE-09D28CFDE3E6}"; private IContentType _contentType; diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/cl.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/cl.snippet deleted file mode 100644 index 6d3aa5d79..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/cl.snippet +++ /dev/null @@ -1,26 +0,0 @@ - - - -
- cl - Code Snippet for a Console message - cl - Microsoft Corporation - - Expansion - -
- - - - message - message - - - - - - -
-
\ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/dowhile.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/dowhile.snippet deleted file mode 100644 index 46d13a460..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/dowhile.snippet +++ /dev/null @@ -1,32 +0,0 @@ - - - -
- dowhile - Code Snippet for a Do...While Loop - do - Microsoft Corporation - - SurroundsWith - Expansion - -
- - - - true - true - - - - - - -
-
- diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/else.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/else.snippet deleted file mode 100644 index 2e64c479e..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/else.snippet +++ /dev/null @@ -1,25 +0,0 @@ - - - -
- else - Code Snippet for an Else Statement - else - Microsoft Corporation - - SurroundsWith - Expansion - -
- - - - - -
-
- diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_delete.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_delete.snippet deleted file mode 100644 index 15de71c26..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_delete.snippet +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- express_delete - Code Snippet for handling a DELETE request with Express - expdelete - Microsoft Corporation - - Expansion - -
- - - - Hello World - Hello World - - - route - route - - - - - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_get.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_get.snippet deleted file mode 100644 index f5d83b6e2..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_get.snippet +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- express_get - Code Snippet for handling a GET request with Express - expget - Microsoft Corporation - - Expansion - -
- - - - Hello World - Hello World - - - route - route - - - - - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_post.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_post.snippet deleted file mode 100644 index 19356ef13..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_post.snippet +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- express_post - Code Snippet for handling a POST request with Express - exppost - Microsoft Corporation - - Expansion - -
- - - - Hello World - Hello World - - - route - route - - - - - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_put.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_put.snippet deleted file mode 100644 index 83a83b6b3..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/express_put.snippet +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- express_put - Code Snippet for handling a PUT request with Express - expput - Microsoft Corporation - - Expansion - -
- - - - Hello World - Hello World - - - route - route - - - - - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/for.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/for.snippet deleted file mode 100644 index e8097685d..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/for.snippet +++ /dev/null @@ -1,34 +0,0 @@ - - - -
- for - Code Snippet for a For Loop - for - Microsoft Corporation - - SurroundsWith - Expansion - -
- - - - length - length - - - i - i - - - - - - -
-
\ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forin.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forin.snippet deleted file mode 100644 index 6ec1ce352..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forin.snippet +++ /dev/null @@ -1,34 +0,0 @@ - - - -
- forin - Code Snippet for For...In Loop - forin - Microsoft Corporation - - SurroundsWith - Expansion - -
- - - - property - i - - - object - o - - - - - - -
-
\ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forprops.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forprops.snippet deleted file mode 100644 index 63fc76dbd..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forprops.snippet +++ /dev/null @@ -1,36 +0,0 @@ - - - -
- forprops - Code Snippet for iterating through the properties of an object - forprops - Microsoft Corporation - - SurroundsWith - Expansion - -
- - - - property - property - - - object - object - - - - - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forr.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forr.snippet deleted file mode 100644 index 734d79daa..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/forr.snippet +++ /dev/null @@ -1,34 +0,0 @@ - - - -
- forr - Code Snippet for a reverse For Loop - forr - Microsoft Corporation - - SurroundsWith - Expansion - -
- - - - length - length - - - i - i - - - - = 0; $i$--) { - $selected$$end$ -}; -]]> - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/function.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/function.snippet deleted file mode 100644 index 6b4b7e8b2..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/function.snippet +++ /dev/null @@ -1,30 +0,0 @@ - - - -
- function - Code Snippet for a Function - function - Microsoft Corporation - - SurroundsWith - Expansion - -
- - - - myFunction - myFunction - - - - - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/if.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/if.snippet deleted file mode 100644 index d042eaaeb..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/if.snippet +++ /dev/null @@ -1,30 +0,0 @@ - - - -
- if - Code Snippet for an If Statement - if - Microsoft Corporation - - SurroundsWith - Expansion - -
- - - - true - true - - - - - - -
-
\ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/iife.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/iife.snippet deleted file mode 100644 index 09b6e774d..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/iife.snippet +++ /dev/null @@ -1,30 +0,0 @@ - - - -
- iife - Code Snippet for an Immediatly-Invoked Function Expression - iife - Microsoft Corporation - - SurroundsWith - Expansion - -
- - - - undefined - undefined - - - - - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/parse.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/parse.snippet deleted file mode 100644 index 4883ad553..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/parse.snippet +++ /dev/null @@ -1,26 +0,0 @@ - - - -
- parse - Code Snippet for parsing a JSON string - parse - Microsoft Corporation - - Expansion - -
- - - - myVar - myVar - - - - - - -
-
\ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/readfile.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/readfile.snippet deleted file mode 100644 index d50bb37f9..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/readfile.snippet +++ /dev/null @@ -1,34 +0,0 @@ - - - -
- readfile - Code Snippet for reading a file using the fs module - readfile - Microsoft Corporation - - Expansion - -
- - - - file - file - - - e - e - - - - - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/readstream.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/readstream.snippet deleted file mode 100644 index 2f31373e2..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/readstream.snippet +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- readstream - Code Snippet for streaming data - readstream - Microsoft Corporation - - Expansion - -
- - - - path - path - - - - - - -
-
\ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/require.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/require.snippet deleted file mode 100644 index c4f45d70c..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/require.snippet +++ /dev/null @@ -1,26 +0,0 @@ - - - -
- require - Code Snippet for requiring a module - require - Microsoft Corporation - - Expansion - -
- - - - myModule - myModule - - - - - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/server.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/server.snippet deleted file mode 100644 index 5094828e6..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/server.snippet +++ /dev/null @@ -1,33 +0,0 @@ - - - -
- server - Code Snippet for a basic server - server - Microsoft Corporation - - Expansion - -
- - - - message - message - - - - - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/stringify.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/stringify.snippet deleted file mode 100644 index 3d66dab32..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/stringify.snippet +++ /dev/null @@ -1,26 +0,0 @@ - - - -
- stringify - Code Snippet to stringify a Javascript value using JSON - stringify - Microsoft Corporation - - Expansion - -
- - - - object - object - - - - - - -
-
\ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/switch.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/switch.snippet deleted file mode 100644 index 96d8edd78..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/switch.snippet +++ /dev/null @@ -1,29 +0,0 @@ - - - -
- switch - Code Snippet for a Switch Statement - switch - Microsoft Corporation - - Expansion - -
- - - - switch_on - switch_on - - - - - - -
-
\ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/try.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/try.snippet deleted file mode 100644 index c7cf135e9..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/try.snippet +++ /dev/null @@ -1,32 +0,0 @@ - - - -
- try - Code Snippet for a Try...Catch Statement - try - Microsoft Corporation - - Expansion - SurroundWith - -
- - - - e - e - - - - - - -
-
diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/tryf.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/tryf.snippet deleted file mode 100644 index e5beeae2b..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/tryf.snippet +++ /dev/null @@ -1,34 +0,0 @@ - - - -
- tryf - Code Snippet for a Try, Catch, Finally Statement - tryf - Microsoft Corporation - - Expansion - SurroundWith - -
- - - - e - e - - - - - - -
-
\ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/while.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/while.snippet deleted file mode 100644 index 85222014a..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/while.snippet +++ /dev/null @@ -1,30 +0,0 @@ - - - -
- while - Code Snippet for a While Loop - while - Microsoft Corporation - - SurroundsWith - Expansion - -
- - - - true - true - - - - - - -
-
\ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/with.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/with.snippet deleted file mode 100644 index e1ffb7946..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Nodejs/with.snippet +++ /dev/null @@ -1,30 +0,0 @@ - - - -
- with - Code Snippet for a With Statement - with - Microsoft Corporation - - SurroundsWith - Expansion - -
- - - - o - o - - - - - - -
-
\ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/SnippetsIndex.xml b/Nodejs/Product/Nodejs/Snippets/1033/SnippetsIndex.xml deleted file mode 100644 index 24556af7c..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/SnippetsIndex.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - on - true - 1033 - Snippets\%LCID%\Test\ - Test - - - on - true - 1033 - Snippets\%LCID%\Nodejs\ - Nodejs - - - \ No newline at end of file diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Test/describe.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Test/describe.snippet deleted file mode 100644 index 888805a0a..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Test/describe.snippet +++ /dev/null @@ -1,31 +0,0 @@ - - - -
- describe - Code Snippet for a Describe statement using Mochajs - des - Microsoft Corporation - - Expansion - SurroundsWith - -
- - - - myFunction - myFunction - - - - - - -
-
- diff --git a/Nodejs/Product/Nodejs/Snippets/1033/Test/it.snippet b/Nodejs/Product/Nodejs/Snippets/1033/Test/it.snippet deleted file mode 100644 index c6aca263f..000000000 --- a/Nodejs/Product/Nodejs/Snippets/1033/Test/it.snippet +++ /dev/null @@ -1,31 +0,0 @@ - - - -
- it - Code Snippet for an It statement using Mochajs - it - Microsoft Corporation - - Expansion - SurroundsWith - -
- - - - message - should work - - - - - - -
-
- diff --git a/Nodejs/Tests/Core.UI/Nodejs.Tests.UI.csproj b/Nodejs/Tests/Core.UI/Nodejs.Tests.UI.csproj index d2138cf9f..ed00e6047 100644 --- a/Nodejs/Tests/Core.UI/Nodejs.Tests.UI.csproj +++ b/Nodejs/Tests/Core.UI/Nodejs.Tests.UI.csproj @@ -114,7 +114,6 @@ - @@ -129,7 +128,6 @@ - diff --git a/Nodejs/Tests/Core.UI/ProjectTests.cs b/Nodejs/Tests/Core.UI/ProjectTests.cs deleted file mode 100644 index 1f262ab3d..000000000 --- a/Nodejs/Tests/Core.UI/ProjectTests.cs +++ /dev/null @@ -1,915 +0,0 @@ -//*********************************************************// -// Copyright (c) Microsoft. All rights reserved. -// -// Apache 2.0 License -// -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. -// -//*********************************************************// - -using System; -using System.ComponentModel; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using System.Windows.Automation; -using EnvDTE; -using Microsoft.NodejsTools; -using Microsoft.NodejsTools.Project; -using Microsoft.VisualStudio.Language.Intellisense; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using TestUtilities; -using TestUtilities.Nodejs; -using TestUtilities.UI; -using TestUtilities.UI.Nodejs; - -namespace Microsoft.Nodejs.Tests.UI { - [TestClass] - public class ProjectTests { - [ClassInitialize] - public static void DoDeployment(TestContext context) { - AssertListener.Initialize(); - NodejsTestData.Deploy(); - } - - /// - /// https://nodejstools.codeplex.com/workitem/270 - /// - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void SnippetsDisabled() { - using (var app = new VisualStudioApp()) { - Window window; - var openFile = OpenProjectItem(app, "server.js", out window); - - openFile.MoveCaret(7, 1); - - // we need to ensure the snippets are initialized by starting - // and dismissing an intellisense session. - Keyboard.Type(Keyboard.CtrlSpace.ToString()); - Keyboard.PressAndRelease(System.Windows.Input.Key.Escape); - - Keyboard.Type("functio"); - System.Threading.Thread.Sleep(2000); - Keyboard.Type("\t"); - openFile.WaitForText(@"var http = require('http'); - -var port = process.env.port || 1337; -var mymod = require('./mymod.js'); -var mutatemod = require('./mutatemod.js'); - -function -http.createServer(function (req, res) { - res.writeHead(200, { 'Content-Type': 'text/plain' }); - res.end('Hello World\n'); -}).listen(port); -"); - } - } - - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void NoAutoFormattingEnter() { - using (var app = new VisualStudioApp()) { - Window window; - var openFile = OpenProjectItem(app, "server.js", out window); - - openFile.MoveCaret(8, 40); - Keyboard.Type("\r"); - openFile.WaitForText(@"var http = require('http'); - -var port = process.env.port || 1337; -var mymod = require('./mymod.js'); -var mutatemod = require('./mutatemod.js'); - - -http.createServer(function (req, res) { - - res.writeHead(200, { 'Content-Type': 'text/plain' }); - res.end('Hello World\n'); -}).listen(port); -"); - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void NoAutoFormattingCloseFunction() { - using (var app = new VisualStudioApp()) { - Window window; - var openFile = OpenProjectItem(app, "server.js", out window); - - openFile.MoveCaret(8, 40); - Keyboard.Type("\rfunction f() { }"); - var text = openFile.Text; - openFile.WaitForText(@"var http = require('http'); - -var port = process.env.port || 1337; -var mymod = require('./mymod.js'); -var mutatemod = require('./mutatemod.js'); - - -http.createServer(function (req, res) { - function f() { } - res.writeHead(200, { 'Content-Type': 'text/plain' }); - res.end('Hello World\n'); -}).listen(port); -"); - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void NoAutoFormattingPaste() { - using (var app = new VisualStudioApp()) { - Window window; - var openFile = OpenProjectItem(app, "server.js", out window); - - openFile.MoveCaret(8, 40); - openFile.Invoke(() => System.Windows.Clipboard.SetText("\r\n")); - Keyboard.ControlV(); - openFile.WaitForText(@"var http = require('http'); - -var port = process.env.port || 1337; -var mymod = require('./mymod.js'); -var mutatemod = require('./mutatemod.js'); - - -http.createServer(function (req, res) { - - res.writeHead(200, { 'Content-Type': 'text/plain' }); - res.end('Hello World\n'); -}).listen(port); -"); - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void NoReferences() { - Window window; - using (var app = new VisualStudioApp()) { - var openFile = OpenProjectItem(app, "server.js", out window); - using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { - var solutionExplorer = app.OpenSolutionExplorer(); - solutionExplorer.WaitForItemRemoved("Solution 'NodeAppWithModule' (1 project)", "NodeAppWithModule", "References"); - } - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void GlobalIntellisense() { - using (var app = new VisualStudioApp()) { - Window window; - var openFile = OpenProjectItem(app, "server.js", out window); - - openFile.MoveCaret(6, 1); - - Keyboard.Type("process."); - using (var session = openFile.WaitForSession()) { - - var completions = session.Session.CompletionSets.First().Completions.Select(x => x.InsertionText); - Assert.IsTrue(completions.Contains("abort")); - Assert.IsTrue(completions.Contains("chdir")); - } - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void RequireIntellisenseExpanded() { - - var testCases = new[] { - new { File="server.js", Line = 4, Type = "mymod.", Expected = "mymod_export" }, - new { File="server.js", Line = 8, Type = "mymod2.", Expected = "mymod_export" }, - new { File="server.js", Line = 12, Type = "mymod3.", Expected = "__filename" }, - new { File="server.js", Line = 19, Type = "foo.", Expected = "foo_export" }, - new { File="server.js", Line = 22, Type = "bar.", Expected = "bar_entry" }, - new { File="server.js", Line = 25, Type = "bar2.", Expected = "bar2_entry" }, - new { File="server.js", Line = 28, Type = "dup.", Expected = "node_modules_dup" }, - new { File="server.js", Line = 31, Type = "dup1.", Expected = "top_level" }, - new { File="server.js", Line = 34, Type = "dup2.", Expected = "top_level" }, - new { File="server.js", Line = 37, Type = "baz_dup.", Expected = "baz_dup" }, - new { File="server.js", Line = 40, Type = "baz_dup2.", Expected = "baz_dup" }, - new { File="server.js", Line = 42, Type = "recursive.", Expected = "recursive1" }, - new { File="server.js", Line = 42, Type = "recursive.", Expected = "recursive2" }, - new { File="server.js", Line = 48, Type = "nested.", Expected = "__filename" }, - new { File="server.js", Line = 54, Type = "indexfolder.", Expected = "indexfolder" }, - new { File="server.js", Line = 56, Type = "indexfolder2.", Expected = "indexfolder" }, - new { File="server.js", Line = 60, Type = "resolve_path.", Expected = "indexfolder" }, - - new { File="node_modules\\mymod.js", Line = 5, Type = "dup.", Expected = "node_modules_dup" }, - new { File="node_modules\\mymod.js", Line = 8, Type = "dup0.", Expected = "node_modules_dup" }, - new { File="node_modules\\mymod.js", Line = 11, Type = "dup1.", Expected = "node_modules_dup" }, - new { File="node_modules\\mymod.js", Line = 14, Type = "dup2.", Expected = "node_modules_dup" }, - new { File="node_modules\\mymod.js", Line = 17, Type = "dup3.", Expected = "dup" }, - - new { File="node_modules\\foo\\index.js", Line = 5, Type = "dup.", Expected = "foo_node_modules" }, - new { File="node_modules\\foo\\index.js", Line = 8, Type = "dup1.", Expected = "dup" }, - new { File="node_modules\\foo\\index.js", Line = 11, Type = "dup2.", Expected = "dup" }, - new { File="node_modules\\foo\\index.js", Line = 14, Type = "other.", Expected = "other" }, - new { File="node_modules\\foo\\index.js", Line = 17, Type = "other2.", Expected = "other" }, - new { File="node_modules\\foo\\index.js", Line = 20, Type = "other3.", Expected = "__filename" }, - new { File="node_modules\\foo\\index.js", Line = 27, Type = "other4.", Expected = "__filename" }, - - new { File="baz\\dup.js", Line = 3, Type = "parent_dup.", Expected = "top_level" }, - new { File="baz\\dup.js", Line = 6, Type = "bar.", Expected = "bar_entry" }, - new { File="baz\\dup.js", Line = 9, Type = "parent_dup2.", Expected = "top_level" }, - }; - - string text = null; - string curFile = null; - Window window; - EditorWindow openFile = null; - using (var app = new VisualStudioApp()) { - - foreach (var testCase in testCases) { - if (testCase.File != curFile) { - openFile = OpenProjectItem(app, testCase.File, out window, @"TestData\RequireTestApp\RequireTestApp.sln"); - app.OpenSolutionExplorer(); - app.SolutionExplorerTreeView.WaitForItem("Solution 'RequireTestApp' (1 project)", "RequireTestApp", "dup.js"); - text = openFile.Text; - curFile = testCase.File; - } - - Console.WriteLine("{0} {1}", testCase.Line, testCase.Type); - - openFile.MoveCaret(testCase.Line, 1); - openFile.Invoke(() => openFile.TextView.Caret.EnsureVisible()); - openFile.SetFocus(); - Keyboard.Type(testCase.Type); - using (var session = openFile.WaitForSession()) { - var completions = session.Session.CompletionSets.First().Completions.Select(x => x.InsertionText); - Assert.IsTrue(completions.Contains(testCase.Expected)); - Keyboard.Type(System.Windows.Input.Key.Escape); - for (int i = 0; i < testCase.Type.Length; i++) { - Keyboard.Type(System.Windows.Input.Key.Back); - } - - openFile.WaitForText(text); - } - } - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void GlobalIntellisenseProjectReload() { - Window window; - using (var app = new VisualStudioApp()) { - app.OpenProject(Path.GetFullPath(@"TestData\NodeAppWithModule2\NodeAppWithModule.sln")); - - using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { - app.OpenSolutionExplorer(); - var projectName = "NodeAppWithModule"; - var project = app.SolutionExplorerTreeView.WaitForItem( - "Solution '" + projectName + "' (1 project)", - projectName); - - var projectNode = new TreeNode(project); - projectNode.SetFocus(); - - System.Threading.Thread.Sleep(2000); - - app.Dte.ExecuteCommand("Project.UnloadProject"); - - project = app.SolutionExplorerTreeView.WaitForItem( - "Solution '" + projectName + "' (0 projects)", - projectName + " (unavailable)"); - - projectNode = new TreeNode(project); - projectNode.Select(); - - System.Threading.Thread.Sleep(2000); - - app.Dte.ExecuteCommand("Project.ReloadProject"); - - Assert.IsNotNull( - app.SolutionExplorerTreeView.WaitForItem( - "Solution '" + projectName + "' (1 project)", - projectName, - "server.js" - ), - "project not reloaded" - ); - - var openFile = OpenItem(app, "server.js", app.Dte.Solution.Projects.Item(1), out window); - - openFile.MoveCaret(6, 1); - Keyboard.Type("process."); - using (var session = openFile.WaitForSession()) { - - var completions = session.Session.CompletionSets.First().Completions.Select(x => x.InsertionText); - Assert.IsTrue(completions.Contains("abort")); - Assert.IsTrue(completions.Contains("chdir")); - } - } - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void UserModule() { - using (var app = new VisualStudioApp()) { - Window window; - var openFile = OpenProjectItem(app, "server.js", out window); - - openFile.MoveCaret(6, 1); - Keyboard.Type("mymod."); - using (var session = openFile.WaitForSession()) { - - var completions = session.Session.CompletionSets.First().Completions.Select(x => x.InsertionText); - Assert.IsTrue(completions.Contains("area")); - Assert.IsTrue(completions.Contains("circumference")); - } - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void AddNewItem() { - Window window; - - using (var app = new VisualStudioApp()) { - var openFile = OpenProjectItem(app, "server.js", out window); - - using (var newItem = NewItemDialog.FromDte(app)) { - newItem.FileName = "NewJSFile.js"; - newItem.OK(); - } - - System.Threading.Thread.Sleep(250); - - var solutionFolder = app.Dte.Solution.Projects.Item(1).ProjectItems; - Assert.AreNotEqual(null, solutionFolder.Item("NewJSFile.js")); - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void EnterCompletion() { - Window window; - using (var app = new VisualStudioApp()) { - var openFile = OpenProjectItem(app, "server.js", out window); - - openFile.MoveCaret(6, 1); - Keyboard.Type("http."); - System.Threading.Thread.Sleep(3000); - Keyboard.Type("Cli\r"); - openFile.WaitForText(@"var http = require('http'); - -var port = process.env.port || 1337; -var mymod = require('./mymod.js'); -var mutatemod = require('./mutatemod.js'); -http.ClientRequest - -http.createServer(function (req, res) { - res.writeHead(200, { 'Content-Type': 'text/plain' }); - res.end('Hello World\n'); -}).listen(port); -"); - } - } - - /// - /// Tests completions against builtin node modules. - /// - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void ModuleCompletions() { - Window window; - - using (var app = new VisualStudioApp()) { - var openFile = OpenProjectItem(app, "intellisensemod.js", out window); - - openFile.MoveCaret(3, 1); - Keyboard.Type("server."); - System.Threading.Thread.Sleep(3000); - Keyboard.Type("lis\r"); - openFile.WaitForText(@"var http = require('http'); -var server = http.createServer(null); // server.listen -server.listen - -var sd = require('stringdecoder'); // sd.StringDecoder(); - - -"); - - openFile.MoveCaret(6, 1); - Keyboard.Type("sd."); - System.Threading.Thread.Sleep(3000); - Keyboard.Type("Str\r"); - openFile.WaitForText(@"var http = require('http'); -var server = http.createServer(null); // server.listen -server.listen - -var sd = require('stringdecoder'); // sd.StringDecoder(); -sd.StringDecoder - -"); - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void NewProject() { - using (var app = new VisualStudioApp()) { - using (var newProjDialog = app.FileNewProject()) { - newProjDialog.FocusLanguageNode("JavaScript"); - - var nodejsApp = newProjDialog.ProjectTypes.FindItem(NodejsVisualStudioApp.JavascriptWebAppTemplate); - nodejsApp.Select(); - - newProjDialog.OK(); - } - - // wait for new solution to load... - for (int i = 0; i < 40 && app.Dte.Solution.Projects.Count == 0; i++) { - System.Threading.Thread.Sleep(250); - } - - app.OpenSolutionExplorer(); - app.SolutionExplorerTreeView.WaitForItem( - "Solution '" + app.Dte.Solution.Projects.Item(1).Name + "' (1 project)", - app.Dte.Solution.Projects.Item(1).Name, - "server.js" - ); - var projItem = app.SolutionExplorerTreeView.WaitForItemRemoved( - "Solution '" + app.Dte.Solution.Projects.Item(1).Name + "' (1 project)", - app.Dte.Solution.Projects.Item(1).Name, - "Web.config" - ); - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void NewAzureProject() { - using (var app = new VisualStudioApp()) { - using (var newProjDialog = app.FileNewProject()) { - newProjDialog.FocusLanguageNode("JavaScript"); - - var azureApp = newProjDialog.ProjectTypes.FindItem(NodejsVisualStudioApp.JavaScriptAzureWebAppTemplate); - azureApp.Select(); - newProjDialog.OK(); - } - - // wait for new solution to load... - for (int i = 0; i < 40 && app.Dte.Solution.Projects.Count == 0; i++) { - System.Threading.Thread.Sleep(250); - } - - app.OpenSolutionExplorer(); - app.SolutionExplorerTreeView.WaitForItem( - "Solution '" + app.Dte.Solution.Projects.Item(1).Name + "' (1 project)", - app.Dte.Solution.Projects.Item(1).Name, - "server.js" - ); - app.SolutionExplorerTreeView.WaitForItem( - "Solution '" + app.Dte.Solution.Projects.Item(1).Name + "' (1 project)", - app.Dte.Solution.Projects.Item(1).Name, - "Web.config" - ); - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void AutomationProject() { - using (var app = new VisualStudioApp()) { - var project = app.OpenProject(@"TestData\NodeAppWithModule\NodeAppWithModule.sln"); - - using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { - Assert.AreEqual("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}", project.Kind.ToUpper()); - // we don't yet expose a VSProject interface here, if we did we'd need tests for it, but it doesn't support - // any functionality we care about/implement yet. - Assert.AreEqual(typeof(NodejsProjectNode), project.Object.GetType()); - - Assert.AreEqual(true, project.Saved); - project.Saved = false; - Assert.AreEqual(false, project.Saved); - project.Saved = true; - - Assert.AreEqual(null, project.Globals); - Assert.AreEqual("{04726c27-8125-471a-bac0-2301d273db5e}", project.ExtenderCATID); - var extNames = project.ExtenderNames; - Assert.AreEqual(typeof(string[]), extNames.GetType()); - Assert.AreEqual(2, ((string[])extNames).Length); - Assert.AreEqual(null, project.ParentProjectItem); - Assert.AreEqual(null, project.CodeModel); - AssertError(() => project.get_Extender(null)); - AssertError(() => project.get_Extender("DoesNotExist")); - Assert.AreEqual(null, project.Collection); - - foreach (ProjectItem item in project.ProjectItems) { - Assert.AreEqual(item.Name, project.ProjectItems.Item(1).Name); - break; - } - - Assert.AreEqual(app.Dte, project.ProjectItems.DTE); - Assert.AreEqual(project, project.ProjectItems.Parent); - Assert.AreEqual(null, project.ProjectItems.Kind); - - AssertError(() => project.ProjectItems.Item(-1)); - AssertError(() => project.ProjectItems.Item(0)); - } - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void SetAsStartupFile() { - using (var app = new VisualStudioApp()) { - var project = app.OpenProject(@"TestData\NodeAppWithModule\NodeAppWithModule.sln"); - - using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { - // wait for new solution to load... - for (int i = 0; i < 40 && app.Dte.Solution.Projects.Count == 0; i++) { - System.Threading.Thread.Sleep(250); - } - - app.OpenSolutionExplorer(); - var item = app.SolutionExplorerTreeView.WaitForItem( - "Solution '" + app.Dte.Solution.Projects.Item(1).Name + "' (1 project)", - app.Dte.Solution.Projects.Item(1).Name, - "mymod.js" - ); - - AutomationWrapper.Select(item); - app.Dte.ExecuteCommand("Project.SetasNode.jsStartupFile"); - - string startupFile = null; - for (int i = 0; i < 40; i++) { - startupFile = (string)project.Properties.Item("StartupFile").Value; - if (startupFile == "mymod.js") { - break; - } - System.Threading.Thread.Sleep(250); - } - Assert.AreEqual(startupFile, Path.Combine(Environment.CurrentDirectory, @"TestData\NodeAppWithModule\NodeAppWithModule", "mymod.js")); - } - } - } - - private static void AssertError(Action action) where T : Exception { - try { - action(); - Assert.Fail(); - } catch (T) { - } - } - - private static EditorWindow OpenProjectItem(VisualStudioApp app, string startItem, out Window window, string projectName = @"TestData\NodeAppWithModule\NodeAppWithModule.sln") { - var project = app.OpenProject(projectName, startItem); - - return OpenItem(app, startItem, project, out window); - } - - private static EditorWindow OpenItem(VisualStudioApp app, string startItem, Project project, out Window window) { - EnvDTE.ProjectItem item = null; - if (startItem.IndexOf('\\') != -1) { - var items = project.ProjectItems; - foreach (var itemName in startItem.Split('\\')) { - Console.WriteLine(itemName); - item = items.Item(itemName); - items = item.ProjectItems; - } - } else { - item = project.ProjectItems.Item(startItem); - } - - Assert.IsNotNull(item); - - window = item.Open(); - window.Activate(); - return app.GetDocument(item.Document.FullName); - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void ProjectProperties() { - for (int mode = 0; mode < 2; mode++) { - using (var app = new VisualStudioApp()) { - var testFile = Path.Combine(Path.GetTempPath(), "nodejstest.txt"); - if (File.Exists(testFile)) { - File.Delete(testFile); - } - - var project = OpenProjectAndRun(app, @"TestData\NodejsProjectPropertiesTest\NodejsProjectPropertiesTest.sln", "server.js", true, debug: mode == 0); - - for (int i = 0; i < 30 && !File.Exists(testFile); i++) { - System.Threading.Thread.Sleep(250); - } - - Assert.IsTrue(File.Exists(testFile), "test file not created"); - var lines = File.ReadAllLines(testFile); - - Assert.IsTrue(lines[0].Contains("scriptargs"), "no scriptargs"); - Assert.IsTrue(lines[0].Contains("server.js"), "missing filename"); - Assert.IsFalse(lines[0].Contains("--harmony"), "interpreter argument leaked to script"); - Assert.IsTrue(lines[1].Contains("--harmony"), "missing interpreter argument"); - Assert.AreEqual("port: 1234", lines[2]); - Assert.AreEqual("cwd: C:\\", lines[3]); - } - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void BrowserLaunch() { - for (int mode = 0; mode < 2; mode++) { - var startingProcesses = System.Diagnostics.Process.GetProcessesByName("iexplore").Select(x => x.Id).ToSet(); - - using (var app = new VisualStudioApp()) { - var testFile = Path.Combine(Path.GetTempPath(), "nodejstest.txt"); - if (File.Exists(testFile)) { - File.Delete(testFile); - } - - var project = OpenProjectAndRun(app, @"TestData\NodejsProjectPropertiesTest\NodejsProjectPropertiesTest.sln", "server2.js", true, debug: mode == 0); - - for (int i = 0; i < 30 && !File.Exists(testFile); i++) { - System.Threading.Thread.Sleep(250); - } - - Assert.IsTrue(File.Exists(testFile), "test file not created"); - } - - System.Threading.Thread.Sleep(2000); - var endingProcesses = System.Diagnostics.Process.GetProcessesByName("iexplore").Select(x => x.Id); - var newProcesses = endingProcesses.Except(startingProcesses).ToArray(); - - if (mode == 0) { - // new processes should have been shutdown when debugging stopped - Assert.AreEqual(0, newProcesses.Length); - } else { - // no debugging, process will hang around - Assert.IsTrue(newProcesses.Length > 0); - foreach (var proc in newProcesses) { - Console.WriteLine("Killing process {0}", proc); - System.Diagnostics.Process.GetProcessById(proc).Kill(); - } - } - } - } - - internal static Project OpenProjectAndRun(VisualStudioApp app, string projName, string filename, bool setStartupItem = true, bool debug = true) { - var project = app.OpenProject(projName, filename, setStartupItem: setStartupItem); - - if (debug) { - app.Dte.ExecuteCommand("Debug.Start"); - } else { - app.Dte.ExecuteCommand("Debug.StartWithoutDebugging"); - } - - return project; - } - - private string CreateTempPathOfLength(int length) { - var path = TestData.GetTempPath(randomSubPath: true) + "\\"; - - int padding = length - path.Length; - if (padding <= 0) { - Assert.Inconclusive("Could not obtain a base directory with a sufficiently short path."); - } - - path += new string('a', padding); - Directory.CreateDirectory(path); - - return path; - } - - private void DeleteLongPath(string path) { - if (!path.StartsWith(@"\\?\")) { - path = @"\\?\" + path; - } - - Microsoft.VisualStudioTools.Project.WIN32_FIND_DATA wfd; - IntPtr hFind = Microsoft.VisualStudioTools.Project.NativeMethods.FindFirstFile(path + "\\*", out wfd); - if (hFind == Microsoft.VisualStudioTools.Project.NativeMethods.INVALID_HANDLE_VALUE) { - return; - } - - try { - do { - if (wfd.cFileName == "." || wfd.cFileName == "..") { - continue; - } - - string childPath = path; - if (childPath != "") { - childPath += "\\"; - } - childPath += wfd.cFileName; - - bool isDirectory = (wfd.dwFileAttributes & Microsoft.VisualStudioTools.Project.NativeMethods.FILE_ATTRIBUTE_DIRECTORY) != 0; - if (isDirectory) { - DeleteLongPath(childPath); - } else { - Console.WriteLine("DeleteFile " + childPath); - if (!Microsoft.VisualStudioTools.Project.NativeMethods.DeleteFile(childPath)) { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - } - } while (Microsoft.VisualStudioTools.Project.NativeMethods.FindNextFile(hFind, out wfd)); - - Console.WriteLine("RemoveDirectory " + path); - if (!Microsoft.VisualStudioTools.Project.NativeMethods.RemoveDirectory(path)) { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - } finally { - Microsoft.VisualStudioTools.Project.NativeMethods.FindClose(hFind); - } - } - - [TestMethod, Priority(0), TestCategory("Core")] - public void GetLongSubPaths() { - string - basePath = CreateTempPathOfLength(248 - 1 - @"\d\d".Length), - shortFile = basePath + @"\f", - shortDir = basePath + @"\d", - shortShortFile = shortDir + @"\f", - shortShortDir = shortDir + @"\d", - shortLongDir = shortDir + @"\dd", - shortLongFile = shortDir + @"\f.ffffffffffffff", - longFile = basePath + @"\f.ffffffffffffff", - longDir = basePath + @"\d.dd", - longLongFile = longDir + @"\ff", - longLongDir = longDir + @"\dd"; - try { - foreach (var path in new[] { shortDir, shortShortDir, shortLongDir, longDir, longLongDir }) { - Console.WriteLine("CreateDirectory {0}", path); - Assert.IsTrue(NativeMethods.CreateDirectory(@"\\?\" + path, IntPtr.Zero), path); - } - - File.WriteAllText(shortFile, ""); - foreach (var path in new[] { shortShortFile, shortLongFile, longFile, longLongFile }) { - Console.WriteLine("CopyFile {0}", path); - Assert.IsTrue(NativeMethods.CopyFile(shortFile, @"\\?\" + path, true), path); - } - - var longPaths = NodejsProjectNode.GetLongSubPaths(basePath).ToList(); - - // Single() acts as assert here (throws if it doesn't find the element matching the condition). - longPaths.Remove(longPaths.Single(lpi => lpi.FullPath == shortLongFile && !lpi.IsDirectory)); - longPaths.Remove(longPaths.Single(lpi => lpi.FullPath == shortLongDir && lpi.IsDirectory)); - longPaths.Remove(longPaths.Single(lpi => lpi.FullPath == longFile && !lpi.IsDirectory)); - longPaths.Remove(longPaths.Single(lpi => lpi.FullPath == longDir && lpi.IsDirectory)); - // longLongFile and longLongDir should not be reported, because their parent longDir is already reported. - - // There should be no other elements reported. - Assert.AreEqual(0, longPaths.Count); - } finally { - DeleteLongPath(basePath); - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void LongPathCheck() { - string[] expectedLongPaths = { - @"node_modules\azure\node_modules\azure-common\node_modules\xml2js\node_modules\sax\test\trailing-attribute-no-value.js", - @"node_modules\azure\node_modules\azure-common\node_modules\xml2js\node_modules\sax\test\xmlns-xml-default-prefix-attribute.js", - @"node_modules\azure\node_modules\azure-common\node_modules\xml2js\node_modules\sax\test\xmlns-xml-default-redefine.js", - @"node_modules\azure\node_modules\request\node_modules\form-data\node_modules\combined-stream\node_modules", - @"node_modules\azure\node_modules\request\node_modules\http-signature\node_modules\ctype\tst\ctio\uint\tst.roundtrip.js", - }; - - string projectDir = CreateTempPathOfLength(248 - 1 - expectedLongPaths.Min(s => s.Length)); - try { - foreach (var fileName in new[] { "HelloWorld.njsproj", "HelloWorld.sln", "package.json", "README.md", "server.js" }) { - File.Copy(TestData.GetPath(@"TestData\HelloWorld\" + fileName), projectDir + "\\" + fileName); - } - - using (var app = new NodejsVisualStudioApp()) { - try { - NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths = true; - - var project = app.OpenProject(projectDir + "\\HelloWorld.sln"); - - // Wait for new solution to load. - for (int i = 0; i < 40 && app.Dte.Solution.Projects.Count == 0; i++) { - System.Threading.Thread.Sleep(250); - } - - const string interpreterDescription = "Node.js Interactive Window"; - app.Dte.ExecuteCommand("View.Node.jsInteractiveWindow"); - var interactive = app.GetInteractiveWindow(interpreterDescription); - if (interactive == null) { - Assert.Inconclusive("Need " + interpreterDescription); - } - - interactive.WaitForIdleState(); - var npmTask = interactive.ReplWindow.ExecuteCommand(".npm install azure@0.9.12"); - - using (var dialog = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(npmTask)))) { - // The option to offer "npm dedupe" should be there. - var firstCommandLink = dialog.FindByAutomationId("CommandLink_1000"); - Assert.IsNotNull(firstCommandLink); - Assert.IsTrue(firstCommandLink.Current.Name.Contains("npm dedupe")); - - dialog.ClickButtonByAutomationId("ExpandoButton"); - var detailsText = dialog.FindByAutomationId("ExpandedFooterTextLink"); - Assert.IsNotNull(detailsText); - - var reportedLongPaths = - (from line in detailsText.Current.Name.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries) - where line.StartsWith("•") - let nbspIndex = line.IndexOf('\u00A0') - where nbspIndex >= 0 - select line.Substring(1, nbspIndex - 1).Trim() - ).ToArray(); - Console.WriteLine("Reported paths:"); - foreach (var path in reportedLongPaths) { - Console.WriteLine("\t" + path); - } - - reportedLongPaths = reportedLongPaths.Except(expectedLongPaths).ToArray(); - if (reportedLongPaths.Length != 0) { - Console.WriteLine("Unexpected paths:"); - foreach (var path in reportedLongPaths) { - Console.WriteLine("\t" + path); - } - Assert.Fail("Unexpected long paths reported."); - } - - dialog.WaitForClosed(TimeSpan.FromSeconds(1), () => { - // Click the first command button (dedupe). - firstCommandLink.SetFocus(); - Keyboard.Press(System.Windows.Input.Key.Enter); - }); - } - - // Clicking on that button should not change the option. - Assert.IsTrue(NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths); - - interactive.WaitForTextContainsAll("dedupe successfully completed"); - interactive.WaitForIdleState(); - - // npm dedupe won't be able to fix the problem, so we should get the dialog once again. - using (var dialog = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(npmTask)))) { - // The option to offer "npm dedupe" should not be there anymore. - var firstCommandLink = dialog.FindByAutomationId("CommandLink_1000"); - Assert.IsNotNull(firstCommandLink); - Assert.IsFalse(firstCommandLink.Current.Name.Contains("npm dedupe")); - - dialog.WaitForClosed(TimeSpan.FromSeconds(1), () => { - Keyboard.Type("\r"); // click the first command button (do nothing, but warn next time) - }); - } - - npmTask.Wait(1000); - Assert.IsTrue(npmTask.IsCompleted); - - // Clicking on that button should not change the option. - Assert.IsTrue(NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths); - - // Try again to see that the dialog still appears. Any npm command triggers the check. - // and since we didn't do anything to fix the problem, we should still get the dialog. - interactive.WaitForIdleState(); - npmTask = interactive.ReplWindow.ExecuteCommand(".npm list"); - - using (var dialog = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(npmTask)))) { - // The option to offer "npm dedupe" should be there again, since this is a new check. - var firstCommandLink = dialog.FindByAutomationId("CommandLink_1000"); - Assert.IsNotNull(firstCommandLink); - Assert.IsTrue(firstCommandLink.Current.Name.Contains("npm dedupe")); - - dialog.WaitForClosed(TimeSpan.FromSeconds(1), () => { - // Click the third command button (do nothing, do not warn anymore) - firstCommandLink.SetFocus(); - Keyboard.Press(System.Windows.Input.Key.Tab); - Keyboard.Press(System.Windows.Input.Key.Tab); - Keyboard.Press(System.Windows.Input.Key.Enter); - }); - } - - npmTask.Wait(1000); - Assert.IsTrue(npmTask.IsCompleted); - - // Clicking on that button should change the option to false. - Assert.IsFalse(NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths); - - // Try again to see that the dialog does not appear anymore. - interactive.WaitForIdleState(); - npmTask = interactive.ReplWindow.ExecuteCommand(".npm list"); - app.WaitForNoDialog(TimeSpan.FromSeconds(3)); - } finally { - NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths = true; - } - } - } finally { - DeleteLongPath(projectDir); - } - } - } -} diff --git a/Nodejs/Tests/Core.UI/SnippetsTests.cs b/Nodejs/Tests/Core.UI/SnippetsTests.cs deleted file mode 100644 index b3c6e3f41..000000000 --- a/Nodejs/Tests/Core.UI/SnippetsTests.cs +++ /dev/null @@ -1,347 +0,0 @@ - -//*********************************************************// -// Copyright (c) Microsoft. All rights reserved. -// -// Apache 2.0 License -// -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. See the License for the specific language governing -// permissions and limitations under the License. -// -//*********************************************************// - -using System; -using System.Collections.Generic; -using EnvDTE; -using Microsoft.NodejsTools; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using TestUtilities; -using TestUtilities.SharedProject; -using TestUtilities.UI; - -namespace Microsoft.Nodejs.Tests.UI { - [TestClass] - public class SnippetsTests:NodejsProjectTest { - - private static ProjectDefinition BasicProject = Project( - "SnippetsTest", - Compile("server", ""), - Compile("multiline", "one\r\ntwo\r\nthree"), - Compile("nonempty", "nonempty"), - Compile("indented", "if (true) {\r\n \r\n}"), - Compile("braceOnNewLine", "if (true)\r\n{\r\n \r\n}") - ); - - class Snippet { - public readonly string Shortcut; - public readonly string Expected; - public readonly Declaration[] Declarations; - - public Snippet(string shortcut, string expected, params Declaration[] declarations) { - Shortcut = shortcut; - Expected = expected; - Declarations = declarations; - - } - } - - class Declaration { - public readonly string Replacement; - public readonly string Expected; - - public Declaration(string replacement, string expected) { - Replacement = replacement; - Expected = expected; - } - } - - private class SnippetTestOptionHolder : IDisposable { - List _options = new List(); - - public SnippetTestOptionHolder( - bool insertTabs = false, - int indentSize = 4, - int tabSize = 4, - bool braceOnNewLineForControlBlocks = false, - bool braceOnNewLineForFunctions = false) { - - _options.AddRange(new[] { - new OptionHolder("TextEditor", "Node.js", "InsertTabs", insertTabs), - new OptionHolder("TextEditor", "Node.js", "IndentSize", indentSize), - new OptionHolder("TextEditor", "Node.js", "TabSize", tabSize) - }); - - var nodejsOptionsPage = NodejsPackage.Instance.FormattingBracesOptionsPage; - - _options.AddRange(new[] { - new NodejsOptionHolder(nodejsOptionsPage, "BraceOnNewLineForControlBlocks", braceOnNewLineForControlBlocks), - new NodejsOptionHolder(nodejsOptionsPage, "BraceOnNewLineForFunctions", braceOnNewLineForFunctions) - }); - } - - public void Dispose() { - _options.ForEach(option => option.Dispose()); - } - } - - private static readonly Snippet[] BasicSnippets = new Snippet[] { - new Snippet( - "while", - "while (true) {\r\n $body$\r\n};", - new Declaration("false", "while (false) {\r\n $body$\r\n};") - ), - new Snippet( - "if", - "if (true) {\r\n $body$\r\n}", - new Declaration("false", "if (false) {\r\n $body$\r\n}") - ), - new Snippet( - "iife", - "(function (undefined) {\r\n $body$\r\n})();", - new Declaration("name","(function (name) {\r\n $body$\r\n})();") - ), - new Snippet( - "for", - "for (var i = 0; i < length; i++) {\r\n $body$\r\n};", - new Declaration("counter", "for (var counter = 0; counter < length; counter++) {\r\n $body$\r\n};") - ) - }; - - #region Test command "Insert Snippet" - - [TestMethod, Priority(0), TestCategory("Core")] - [HostType("VSTestHost")] - public void InsertSnippet() { - using (var solution = BasicProject.Generate().ToVs()) { - using (new SnippetTestOptionHolder()) { - foreach (var snippet in BasicSnippets) { - TestOneInsertSnippet(solution, snippet, "Nodejs"); - - solution.CloseActiveWindow(vsSaveChanges.vsSaveChangesNo); - } - } - } - } - - private static IEditor TestOneInsertSnippet(IVisualStudioInstance solution, Snippet snippet, string category, string body = "nonempty", string file = "nonempty.js") { - Console.WriteLine("Testing: {0}", snippet.Shortcut); - var server = solution.OpenItem("SnippetsTest", file); - server.Select(1, 1, server.Text.Length); - server.Invoke(() => server.TextView.Caret.EnsureVisible()); - server.SetFocus(); - - solution.ExecuteCommand("Edit.InsertSnippet"); - Keyboard.Type(category + "\t"); - - return VerifySnippet(snippet, body, server, insertViaMenu: true); - } - - #endregion - - #region Test command "Surround With" - - [TestMethod, Priority(0), TestCategory("Core")] - [HostType("VSTestHost")] - public void SurroundWithSnippet() { - using (var solution = BasicProject.Generate().ToVs()) { - using (new SnippetTestOptionHolder()) { - foreach (var snippet in BasicSnippets) { - TestOneSurroundWithSnippet(solution, snippet, "Nodejs"); - - solution.CloseActiveWindow(vsSaveChanges.vsSaveChangesNo); - } - } - } - } - - [TestMethod, Priority(0), TestCategory("Core")] - [HostType("VSTestHost")] - public void SurroundWithMultiline() { - using (var solution = BasicProject.Generate().ToVs()) { - using (new SnippetTestOptionHolder()) { - foreach (var snippet in BasicSnippets) { - TestOneSurroundWithSnippet( - solution, - snippet, - "Nodejs", - "one\r\n two\r\n three", - "multiline.js" - ); - - solution.CloseActiveWindow(vsSaveChanges.vsSaveChangesNo); - } - } - } - } - - private static IEditor TestOneSurroundWithSnippet(IVisualStudioInstance solution, Snippet snippet, string category, string body = "nonempty", string file = "nonempty.js") { - Console.WriteLine("Testing: {0}", snippet.Shortcut); - var server = solution.OpenItem("SnippetsTest", file); - server.Select(1, 1, server.Text.Length); - server.Invoke(() => server.TextView.Caret.EnsureVisible()); - server.SetFocus(); - - solution.ExecuteCommand("Edit.SurroundWith"); - Keyboard.Type(category + "\t"); - - return VerifySnippet(snippet, body, server, insertViaMenu: true); - } - - #endregion - - #region Insert snippet with tab - - [TestMethod, Priority(0), TestCategory("Core")] - [HostType("VSTestHost")] - public void Selected() { - var snippet = new Snippet( - "if", - "if (true) {\r\n $body$\r\n}", - new Declaration("false", "if (false) {\r\n $body$\r\n}") - ); - using (var solution = BasicProject.Generate().ToVs()) { - using (new SnippetTestOptionHolder()) { - var app = TestOneTabSnippet(solution, snippet); - - Keyboard.Type("testing"); - app.WaitForText("if (false) {\r\n testing\r\n}"); - - solution.CloseActiveWindow(vsSaveChanges.vsSaveChangesNo); - } - } - } - - [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] - [HostType("VSTestHost")] - public void BasicSnippetsTab() { - using (var solution = BasicProject.Generate().ToVs()) { - using (new SnippetTestOptionHolder()) { - foreach (var snippet in BasicSnippets) { - TestOneTabSnippet(solution, snippet); - - solution.CloseActiveWindow(vsSaveChanges.vsSaveChangesNo); - } - } - } - } - - private static IEditor TestOneTabSnippet(IVisualStudioInstance solution, Snippet snippet) { - Console.WriteLine("Testing: {0}", snippet.Shortcut); - var server = solution.OpenItem("SnippetsTest", "server.js"); - server.MoveCaret(1, 1); - server.Invoke(() => server.TextView.Caret.EnsureVisible()); - server.SetFocus(); - - return VerifySnippet(snippet, "", server); - } - - private static IEditor VerifySnippet(Snippet snippet, string body, IEditor server, bool insertViaMenu = false) { - if (insertViaMenu) { - Keyboard.Type(snippet.Shortcut + "\t"); // one tab for auto completion, one tab for snippet - } - else { - Keyboard.Type(snippet.Shortcut + "\t\t"); - } - - server.WaitForText(snippet.Expected.Replace("$body$", body)); - - foreach (var decl in snippet.Declarations) { - Console.WriteLine("Declaration: {0}", decl.Replacement); - Keyboard.Type(decl.Replacement); - Keyboard.Type("→"); - server.WaitForText(decl.Expected.Replace("$body$", body)); - Keyboard.Type("\t"); - } - Keyboard.Type("\r"); - return server; - } - - [TestMethod, Priority(0), TestCategory("Core")] - [HostType("VSTestHost")] - public void SelectedIndented() { - using (var solution = BasicProject.Generate().ToVs()) { - using (new SnippetTestOptionHolder()) { - var server = solution.OpenItem("SnippetsTest", "indented.js"); - server.MoveCaret(2, 5); - server.Invoke(() => server.TextView.Caret.EnsureVisible()); - server.SetFocus(); - - Keyboard.Type("if\t\t"); - server.WaitForText("if (true) {\r\n if (true) {\r\n \r\n }\r\n}"); - Keyboard.Type("\r"); - Keyboard.Type("testing"); - server.WaitForText("if (true) {\r\n if (true) {\r\n testing\r\n }\r\n}"); - - solution.CloseActiveWindow(vsSaveChanges.vsSaveChangesNo); - } - } - } - - #endregion - - #region User settings - - [TestMethod, Priority(0), TestCategory("Core")] - [HostType("VSTestHost")] - public void IndentSize() { - var snippet = new Snippet( - "tryf", - "try {\r\n $body$\r\n} catch (e) {\r\n \r\n} finally {\r\n \r\n};", - new Declaration("exception", "try {\r\n $body$\r\n} catch (exception) {\r\n \r\n} finally {\r\n \r\n};") - ); - using (var solution = BasicProject.Generate().ToVs()) { - using (new SnippetTestOptionHolder(insertTabs: false, indentSize: 2, tabSize: 2)) { - TestOneInsertSnippet(solution, snippet, "Nodejs"); - solution.CloseActiveWindow(vsSaveChanges.vsSaveChangesNo); - } - } - } - - [TestMethod, Priority(0), TestCategory("Core")] - [HostType("VSTestHost")] - public void TabIndentation() { - var snippet = new Snippet( - "forprops", - "for (var property in object) {\r\n\tif (object.hasOwnProperty(property)) {\r\n\t\t$body$\r\n\t}\r\n};", - new Declaration("p", "for (var p in object) {\r\n\tif (object.hasOwnProperty(p)) {\r\n\t\t$body$\r\n\t}\r\n};") - ); - using (var solution = BasicProject.Generate().ToVs()) { - using (new SnippetTestOptionHolder(insertTabs: true, indentSize: 8, tabSize: 8)) { - TestOneInsertSnippet(solution, snippet, "Nodejs"); - solution.CloseActiveWindow(vsSaveChanges.vsSaveChangesNo); - } - } - } - - [TestMethod, Priority(0), TestCategory("Core")] - [HostType("VSTestHost")] - public void BraceOnNewLine() { - using (var solution = BasicProject.Generate().ToVs()) { - using (new SnippetTestOptionHolder( - insertTabs: false, - indentSize: 2, - tabSize: 2, - braceOnNewLineForControlBlocks: true, - braceOnNewLineForFunctions: true)) { - - var server = solution.OpenItem("SnippetsTest", "braceOnNewLine.js"); - server.MoveCaret(3, 3); - server.Invoke(() => server.TextView.Caret.EnsureVisible()); - server.SetFocus(); - - Keyboard.Type("try\t\t"); - server.WaitForText("if (true)\r\n{\r\n try\r\n {\r\n \r\n } catch (e)\r\n {\r\n \r\n };\r\n}"); - - solution.CloseActiveWindow(vsSaveChanges.vsSaveChangesNo); - } - } - } - - #endregion - } -} From edb23446a8c66c973a150ec22188695b9467b45b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 9 Sep 2016 15:09:18 -0700 Subject: [PATCH 2/3] Remove snippets from installer too --- .../Setup/NodejsTools/NodejsToolsFiles.proj | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/Nodejs/Setup/NodejsTools/NodejsToolsFiles.proj b/Nodejs/Setup/NodejsTools/NodejsToolsFiles.proj index 63e8e20b0..970e2e261 100644 --- a/Nodejs/Setup/NodejsTools/NodejsToolsFiles.proj +++ b/Nodejs/Setup/NodejsTools/NodejsToolsFiles.proj @@ -94,44 +94,6 @@ ItemTemplates_CloudService_WorkerRole - - - Snippets_1033_Nodejs - - - - Snippets_1033_Test - - - - Snippets_1033 - - TypingsAcquisitionTool From d08ad4f8e2a1cc95b7fe43fa1d96241b12caaade Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 9 Sep 2016 15:12:33 -0700 Subject: [PATCH 3/3] Restore test file, but delete single bad test --- Nodejs/Tests/Core.UI/Nodejs.Tests.UI.csproj | 1 + Nodejs/Tests/Core.UI/ProjectTests.cs | 879 ++++++++++++++++++++ 2 files changed, 880 insertions(+) create mode 100644 Nodejs/Tests/Core.UI/ProjectTests.cs diff --git a/Nodejs/Tests/Core.UI/Nodejs.Tests.UI.csproj b/Nodejs/Tests/Core.UI/Nodejs.Tests.UI.csproj index ed00e6047..38e92742c 100644 --- a/Nodejs/Tests/Core.UI/Nodejs.Tests.UI.csproj +++ b/Nodejs/Tests/Core.UI/Nodejs.Tests.UI.csproj @@ -123,6 +123,7 @@ + diff --git a/Nodejs/Tests/Core.UI/ProjectTests.cs b/Nodejs/Tests/Core.UI/ProjectTests.cs new file mode 100644 index 000000000..4c8dcc2af --- /dev/null +++ b/Nodejs/Tests/Core.UI/ProjectTests.cs @@ -0,0 +1,879 @@ +//*********************************************************// +// Copyright (c) Microsoft. All rights reserved. +// +// Apache 2.0 License +// +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. See the License for the specific language governing +// permissions and limitations under the License. +// +//*********************************************************// + +using System; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Windows.Automation; +using EnvDTE; +using Microsoft.NodejsTools; +using Microsoft.NodejsTools.Project; +using Microsoft.VisualStudio.Language.Intellisense; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TestUtilities; +using TestUtilities.Nodejs; +using TestUtilities.UI; +using TestUtilities.UI.Nodejs; + +namespace Microsoft.Nodejs.Tests.UI { + [TestClass] + public class ProjectTests { + [ClassInitialize] + public static void DoDeployment(TestContext context) { + AssertListener.Initialize(); + NodejsTestData.Deploy(); + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void NoAutoFormattingEnter() { + using (var app = new VisualStudioApp()) { + Window window; + var openFile = OpenProjectItem(app, "server.js", out window); + + openFile.MoveCaret(8, 40); + Keyboard.Type("\r"); + openFile.WaitForText(@"var http = require('http'); + +var port = process.env.port || 1337; +var mymod = require('./mymod.js'); +var mutatemod = require('./mutatemod.js'); + + +http.createServer(function (req, res) { + + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('Hello World\n'); +}).listen(port); +"); + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void NoAutoFormattingCloseFunction() { + using (var app = new VisualStudioApp()) { + Window window; + var openFile = OpenProjectItem(app, "server.js", out window); + + openFile.MoveCaret(8, 40); + Keyboard.Type("\rfunction f() { }"); + var text = openFile.Text; + openFile.WaitForText(@"var http = require('http'); + +var port = process.env.port || 1337; +var mymod = require('./mymod.js'); +var mutatemod = require('./mutatemod.js'); + + +http.createServer(function (req, res) { + function f() { } + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('Hello World\n'); +}).listen(port); +"); + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void NoAutoFormattingPaste() { + using (var app = new VisualStudioApp()) { + Window window; + var openFile = OpenProjectItem(app, "server.js", out window); + + openFile.MoveCaret(8, 40); + openFile.Invoke(() => System.Windows.Clipboard.SetText("\r\n")); + Keyboard.ControlV(); + openFile.WaitForText(@"var http = require('http'); + +var port = process.env.port || 1337; +var mymod = require('./mymod.js'); +var mutatemod = require('./mutatemod.js'); + + +http.createServer(function (req, res) { + + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('Hello World\n'); +}).listen(port); +"); + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void NoReferences() { + Window window; + using (var app = new VisualStudioApp()) { + var openFile = OpenProjectItem(app, "server.js", out window); + using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { + var solutionExplorer = app.OpenSolutionExplorer(); + solutionExplorer.WaitForItemRemoved("Solution 'NodeAppWithModule' (1 project)", "NodeAppWithModule", "References"); + } + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void GlobalIntellisense() { + using (var app = new VisualStudioApp()) { + Window window; + var openFile = OpenProjectItem(app, "server.js", out window); + + openFile.MoveCaret(6, 1); + + Keyboard.Type("process."); + using (var session = openFile.WaitForSession()) { + + var completions = session.Session.CompletionSets.First().Completions.Select(x => x.InsertionText); + Assert.IsTrue(completions.Contains("abort")); + Assert.IsTrue(completions.Contains("chdir")); + } + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void RequireIntellisenseExpanded() { + + var testCases = new[] { + new { File="server.js", Line = 4, Type = "mymod.", Expected = "mymod_export" }, + new { File="server.js", Line = 8, Type = "mymod2.", Expected = "mymod_export" }, + new { File="server.js", Line = 12, Type = "mymod3.", Expected = "__filename" }, + new { File="server.js", Line = 19, Type = "foo.", Expected = "foo_export" }, + new { File="server.js", Line = 22, Type = "bar.", Expected = "bar_entry" }, + new { File="server.js", Line = 25, Type = "bar2.", Expected = "bar2_entry" }, + new { File="server.js", Line = 28, Type = "dup.", Expected = "node_modules_dup" }, + new { File="server.js", Line = 31, Type = "dup1.", Expected = "top_level" }, + new { File="server.js", Line = 34, Type = "dup2.", Expected = "top_level" }, + new { File="server.js", Line = 37, Type = "baz_dup.", Expected = "baz_dup" }, + new { File="server.js", Line = 40, Type = "baz_dup2.", Expected = "baz_dup" }, + new { File="server.js", Line = 42, Type = "recursive.", Expected = "recursive1" }, + new { File="server.js", Line = 42, Type = "recursive.", Expected = "recursive2" }, + new { File="server.js", Line = 48, Type = "nested.", Expected = "__filename" }, + new { File="server.js", Line = 54, Type = "indexfolder.", Expected = "indexfolder" }, + new { File="server.js", Line = 56, Type = "indexfolder2.", Expected = "indexfolder" }, + new { File="server.js", Line = 60, Type = "resolve_path.", Expected = "indexfolder" }, + + new { File="node_modules\\mymod.js", Line = 5, Type = "dup.", Expected = "node_modules_dup" }, + new { File="node_modules\\mymod.js", Line = 8, Type = "dup0.", Expected = "node_modules_dup" }, + new { File="node_modules\\mymod.js", Line = 11, Type = "dup1.", Expected = "node_modules_dup" }, + new { File="node_modules\\mymod.js", Line = 14, Type = "dup2.", Expected = "node_modules_dup" }, + new { File="node_modules\\mymod.js", Line = 17, Type = "dup3.", Expected = "dup" }, + + new { File="node_modules\\foo\\index.js", Line = 5, Type = "dup.", Expected = "foo_node_modules" }, + new { File="node_modules\\foo\\index.js", Line = 8, Type = "dup1.", Expected = "dup" }, + new { File="node_modules\\foo\\index.js", Line = 11, Type = "dup2.", Expected = "dup" }, + new { File="node_modules\\foo\\index.js", Line = 14, Type = "other.", Expected = "other" }, + new { File="node_modules\\foo\\index.js", Line = 17, Type = "other2.", Expected = "other" }, + new { File="node_modules\\foo\\index.js", Line = 20, Type = "other3.", Expected = "__filename" }, + new { File="node_modules\\foo\\index.js", Line = 27, Type = "other4.", Expected = "__filename" }, + + new { File="baz\\dup.js", Line = 3, Type = "parent_dup.", Expected = "top_level" }, + new { File="baz\\dup.js", Line = 6, Type = "bar.", Expected = "bar_entry" }, + new { File="baz\\dup.js", Line = 9, Type = "parent_dup2.", Expected = "top_level" }, + }; + + string text = null; + string curFile = null; + Window window; + EditorWindow openFile = null; + using (var app = new VisualStudioApp()) { + + foreach (var testCase in testCases) { + if (testCase.File != curFile) { + openFile = OpenProjectItem(app, testCase.File, out window, @"TestData\RequireTestApp\RequireTestApp.sln"); + app.OpenSolutionExplorer(); + app.SolutionExplorerTreeView.WaitForItem("Solution 'RequireTestApp' (1 project)", "RequireTestApp", "dup.js"); + text = openFile.Text; + curFile = testCase.File; + } + + Console.WriteLine("{0} {1}", testCase.Line, testCase.Type); + + openFile.MoveCaret(testCase.Line, 1); + openFile.Invoke(() => openFile.TextView.Caret.EnsureVisible()); + openFile.SetFocus(); + Keyboard.Type(testCase.Type); + using (var session = openFile.WaitForSession()) { + var completions = session.Session.CompletionSets.First().Completions.Select(x => x.InsertionText); + Assert.IsTrue(completions.Contains(testCase.Expected)); + Keyboard.Type(System.Windows.Input.Key.Escape); + for (int i = 0; i < testCase.Type.Length; i++) { + Keyboard.Type(System.Windows.Input.Key.Back); + } + + openFile.WaitForText(text); + } + } + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void GlobalIntellisenseProjectReload() { + Window window; + using (var app = new VisualStudioApp()) { + app.OpenProject(Path.GetFullPath(@"TestData\NodeAppWithModule2\NodeAppWithModule.sln")); + + using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { + app.OpenSolutionExplorer(); + var projectName = "NodeAppWithModule"; + var project = app.SolutionExplorerTreeView.WaitForItem( + "Solution '" + projectName + "' (1 project)", + projectName); + + var projectNode = new TreeNode(project); + projectNode.SetFocus(); + + System.Threading.Thread.Sleep(2000); + + app.Dte.ExecuteCommand("Project.UnloadProject"); + + project = app.SolutionExplorerTreeView.WaitForItem( + "Solution '" + projectName + "' (0 projects)", + projectName + " (unavailable)"); + + projectNode = new TreeNode(project); + projectNode.Select(); + + System.Threading.Thread.Sleep(2000); + + app.Dte.ExecuteCommand("Project.ReloadProject"); + + Assert.IsNotNull( + app.SolutionExplorerTreeView.WaitForItem( + "Solution '" + projectName + "' (1 project)", + projectName, + "server.js" + ), + "project not reloaded" + ); + + var openFile = OpenItem(app, "server.js", app.Dte.Solution.Projects.Item(1), out window); + + openFile.MoveCaret(6, 1); + Keyboard.Type("process."); + using (var session = openFile.WaitForSession()) { + + var completions = session.Session.CompletionSets.First().Completions.Select(x => x.InsertionText); + Assert.IsTrue(completions.Contains("abort")); + Assert.IsTrue(completions.Contains("chdir")); + } + } + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void UserModule() { + using (var app = new VisualStudioApp()) { + Window window; + var openFile = OpenProjectItem(app, "server.js", out window); + + openFile.MoveCaret(6, 1); + Keyboard.Type("mymod."); + using (var session = openFile.WaitForSession()) { + + var completions = session.Session.CompletionSets.First().Completions.Select(x => x.InsertionText); + Assert.IsTrue(completions.Contains("area")); + Assert.IsTrue(completions.Contains("circumference")); + } + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void AddNewItem() { + Window window; + + using (var app = new VisualStudioApp()) { + var openFile = OpenProjectItem(app, "server.js", out window); + + using (var newItem = NewItemDialog.FromDte(app)) { + newItem.FileName = "NewJSFile.js"; + newItem.OK(); + } + + System.Threading.Thread.Sleep(250); + + var solutionFolder = app.Dte.Solution.Projects.Item(1).ProjectItems; + Assert.AreNotEqual(null, solutionFolder.Item("NewJSFile.js")); + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void EnterCompletion() { + Window window; + using (var app = new VisualStudioApp()) { + var openFile = OpenProjectItem(app, "server.js", out window); + + openFile.MoveCaret(6, 1); + Keyboard.Type("http."); + System.Threading.Thread.Sleep(3000); + Keyboard.Type("Cli\r"); + openFile.WaitForText(@"var http = require('http'); + +var port = process.env.port || 1337; +var mymod = require('./mymod.js'); +var mutatemod = require('./mutatemod.js'); +http.ClientRequest + +http.createServer(function (req, res) { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('Hello World\n'); +}).listen(port); +"); + } + } + + /// + /// Tests completions against builtin node modules. + /// + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void ModuleCompletions() { + Window window; + + using (var app = new VisualStudioApp()) { + var openFile = OpenProjectItem(app, "intellisensemod.js", out window); + + openFile.MoveCaret(3, 1); + Keyboard.Type("server."); + System.Threading.Thread.Sleep(3000); + Keyboard.Type("lis\r"); + openFile.WaitForText(@"var http = require('http'); +var server = http.createServer(null); // server.listen +server.listen + +var sd = require('stringdecoder'); // sd.StringDecoder(); + + +"); + + openFile.MoveCaret(6, 1); + Keyboard.Type("sd."); + System.Threading.Thread.Sleep(3000); + Keyboard.Type("Str\r"); + openFile.WaitForText(@"var http = require('http'); +var server = http.createServer(null); // server.listen +server.listen + +var sd = require('stringdecoder'); // sd.StringDecoder(); +sd.StringDecoder + +"); + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void NewProject() { + using (var app = new VisualStudioApp()) { + using (var newProjDialog = app.FileNewProject()) { + newProjDialog.FocusLanguageNode("JavaScript"); + + var nodejsApp = newProjDialog.ProjectTypes.FindItem(NodejsVisualStudioApp.JavascriptWebAppTemplate); + nodejsApp.Select(); + + newProjDialog.OK(); + } + + // wait for new solution to load... + for (int i = 0; i < 40 && app.Dte.Solution.Projects.Count == 0; i++) { + System.Threading.Thread.Sleep(250); + } + + app.OpenSolutionExplorer(); + app.SolutionExplorerTreeView.WaitForItem( + "Solution '" + app.Dte.Solution.Projects.Item(1).Name + "' (1 project)", + app.Dte.Solution.Projects.Item(1).Name, + "server.js" + ); + var projItem = app.SolutionExplorerTreeView.WaitForItemRemoved( + "Solution '" + app.Dte.Solution.Projects.Item(1).Name + "' (1 project)", + app.Dte.Solution.Projects.Item(1).Name, + "Web.config" + ); + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void NewAzureProject() { + using (var app = new VisualStudioApp()) { + using (var newProjDialog = app.FileNewProject()) { + newProjDialog.FocusLanguageNode("JavaScript"); + + var azureApp = newProjDialog.ProjectTypes.FindItem(NodejsVisualStudioApp.JavaScriptAzureWebAppTemplate); + azureApp.Select(); + newProjDialog.OK(); + } + + // wait for new solution to load... + for (int i = 0; i < 40 && app.Dte.Solution.Projects.Count == 0; i++) { + System.Threading.Thread.Sleep(250); + } + + app.OpenSolutionExplorer(); + app.SolutionExplorerTreeView.WaitForItem( + "Solution '" + app.Dte.Solution.Projects.Item(1).Name + "' (1 project)", + app.Dte.Solution.Projects.Item(1).Name, + "server.js" + ); + app.SolutionExplorerTreeView.WaitForItem( + "Solution '" + app.Dte.Solution.Projects.Item(1).Name + "' (1 project)", + app.Dte.Solution.Projects.Item(1).Name, + "Web.config" + ); + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void AutomationProject() { + using (var app = new VisualStudioApp()) { + var project = app.OpenProject(@"TestData\NodeAppWithModule\NodeAppWithModule.sln"); + + using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { + Assert.AreEqual("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}", project.Kind.ToUpper()); + // we don't yet expose a VSProject interface here, if we did we'd need tests for it, but it doesn't support + // any functionality we care about/implement yet. + Assert.AreEqual(typeof(NodejsProjectNode), project.Object.GetType()); + + Assert.AreEqual(true, project.Saved); + project.Saved = false; + Assert.AreEqual(false, project.Saved); + project.Saved = true; + + Assert.AreEqual(null, project.Globals); + Assert.AreEqual("{04726c27-8125-471a-bac0-2301d273db5e}", project.ExtenderCATID); + var extNames = project.ExtenderNames; + Assert.AreEqual(typeof(string[]), extNames.GetType()); + Assert.AreEqual(2, ((string[])extNames).Length); + Assert.AreEqual(null, project.ParentProjectItem); + Assert.AreEqual(null, project.CodeModel); + AssertError(() => project.get_Extender(null)); + AssertError(() => project.get_Extender("DoesNotExist")); + Assert.AreEqual(null, project.Collection); + + foreach (ProjectItem item in project.ProjectItems) { + Assert.AreEqual(item.Name, project.ProjectItems.Item(1).Name); + break; + } + + Assert.AreEqual(app.Dte, project.ProjectItems.DTE); + Assert.AreEqual(project, project.ProjectItems.Parent); + Assert.AreEqual(null, project.ProjectItems.Kind); + + AssertError(() => project.ProjectItems.Item(-1)); + AssertError(() => project.ProjectItems.Item(0)); + } + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void SetAsStartupFile() { + using (var app = new VisualStudioApp()) { + var project = app.OpenProject(@"TestData\NodeAppWithModule\NodeAppWithModule.sln"); + + using (new NodejsOptionHolder(NodejsPackage.Instance.GeneralOptionsPage, "ShowBrowserAndNodeLabels", false)) { + // wait for new solution to load... + for (int i = 0; i < 40 && app.Dte.Solution.Projects.Count == 0; i++) { + System.Threading.Thread.Sleep(250); + } + + app.OpenSolutionExplorer(); + var item = app.SolutionExplorerTreeView.WaitForItem( + "Solution '" + app.Dte.Solution.Projects.Item(1).Name + "' (1 project)", + app.Dte.Solution.Projects.Item(1).Name, + "mymod.js" + ); + + AutomationWrapper.Select(item); + app.Dte.ExecuteCommand("Project.SetasNode.jsStartupFile"); + + string startupFile = null; + for (int i = 0; i < 40; i++) { + startupFile = (string)project.Properties.Item("StartupFile").Value; + if (startupFile == "mymod.js") { + break; + } + System.Threading.Thread.Sleep(250); + } + Assert.AreEqual(startupFile, Path.Combine(Environment.CurrentDirectory, @"TestData\NodeAppWithModule\NodeAppWithModule", "mymod.js")); + } + } + } + + private static void AssertError(Action action) where T : Exception { + try { + action(); + Assert.Fail(); + } catch (T) { + } + } + + private static EditorWindow OpenProjectItem(VisualStudioApp app, string startItem, out Window window, string projectName = @"TestData\NodeAppWithModule\NodeAppWithModule.sln") { + var project = app.OpenProject(projectName, startItem); + + return OpenItem(app, startItem, project, out window); + } + + private static EditorWindow OpenItem(VisualStudioApp app, string startItem, Project project, out Window window) { + EnvDTE.ProjectItem item = null; + if (startItem.IndexOf('\\') != -1) { + var items = project.ProjectItems; + foreach (var itemName in startItem.Split('\\')) { + Console.WriteLine(itemName); + item = items.Item(itemName); + items = item.ProjectItems; + } + } else { + item = project.ProjectItems.Item(startItem); + } + + Assert.IsNotNull(item); + + window = item.Open(); + window.Activate(); + return app.GetDocument(item.Document.FullName); + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void ProjectProperties() { + for (int mode = 0; mode < 2; mode++) { + using (var app = new VisualStudioApp()) { + var testFile = Path.Combine(Path.GetTempPath(), "nodejstest.txt"); + if (File.Exists(testFile)) { + File.Delete(testFile); + } + + var project = OpenProjectAndRun(app, @"TestData\NodejsProjectPropertiesTest\NodejsProjectPropertiesTest.sln", "server.js", true, debug: mode == 0); + + for (int i = 0; i < 30 && !File.Exists(testFile); i++) { + System.Threading.Thread.Sleep(250); + } + + Assert.IsTrue(File.Exists(testFile), "test file not created"); + var lines = File.ReadAllLines(testFile); + + Assert.IsTrue(lines[0].Contains("scriptargs"), "no scriptargs"); + Assert.IsTrue(lines[0].Contains("server.js"), "missing filename"); + Assert.IsFalse(lines[0].Contains("--harmony"), "interpreter argument leaked to script"); + Assert.IsTrue(lines[1].Contains("--harmony"), "missing interpreter argument"); + Assert.AreEqual("port: 1234", lines[2]); + Assert.AreEqual("cwd: C:\\", lines[3]); + } + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void BrowserLaunch() { + for (int mode = 0; mode < 2; mode++) { + var startingProcesses = System.Diagnostics.Process.GetProcessesByName("iexplore").Select(x => x.Id).ToSet(); + + using (var app = new VisualStudioApp()) { + var testFile = Path.Combine(Path.GetTempPath(), "nodejstest.txt"); + if (File.Exists(testFile)) { + File.Delete(testFile); + } + + var project = OpenProjectAndRun(app, @"TestData\NodejsProjectPropertiesTest\NodejsProjectPropertiesTest.sln", "server2.js", true, debug: mode == 0); + + for (int i = 0; i < 30 && !File.Exists(testFile); i++) { + System.Threading.Thread.Sleep(250); + } + + Assert.IsTrue(File.Exists(testFile), "test file not created"); + } + + System.Threading.Thread.Sleep(2000); + var endingProcesses = System.Diagnostics.Process.GetProcessesByName("iexplore").Select(x => x.Id); + var newProcesses = endingProcesses.Except(startingProcesses).ToArray(); + + if (mode == 0) { + // new processes should have been shutdown when debugging stopped + Assert.AreEqual(0, newProcesses.Length); + } else { + // no debugging, process will hang around + Assert.IsTrue(newProcesses.Length > 0); + foreach (var proc in newProcesses) { + Console.WriteLine("Killing process {0}", proc); + System.Diagnostics.Process.GetProcessById(proc).Kill(); + } + } + } + } + + internal static Project OpenProjectAndRun(VisualStudioApp app, string projName, string filename, bool setStartupItem = true, bool debug = true) { + var project = app.OpenProject(projName, filename, setStartupItem: setStartupItem); + + if (debug) { + app.Dte.ExecuteCommand("Debug.Start"); + } else { + app.Dte.ExecuteCommand("Debug.StartWithoutDebugging"); + } + + return project; + } + + private string CreateTempPathOfLength(int length) { + var path = TestData.GetTempPath(randomSubPath: true) + "\\"; + + int padding = length - path.Length; + if (padding <= 0) { + Assert.Inconclusive("Could not obtain a base directory with a sufficiently short path."); + } + + path += new string('a', padding); + Directory.CreateDirectory(path); + + return path; + } + + private void DeleteLongPath(string path) { + if (!path.StartsWith(@"\\?\")) { + path = @"\\?\" + path; + } + + Microsoft.VisualStudioTools.Project.WIN32_FIND_DATA wfd; + IntPtr hFind = Microsoft.VisualStudioTools.Project.NativeMethods.FindFirstFile(path + "\\*", out wfd); + if (hFind == Microsoft.VisualStudioTools.Project.NativeMethods.INVALID_HANDLE_VALUE) { + return; + } + + try { + do { + if (wfd.cFileName == "." || wfd.cFileName == "..") { + continue; + } + + string childPath = path; + if (childPath != "") { + childPath += "\\"; + } + childPath += wfd.cFileName; + + bool isDirectory = (wfd.dwFileAttributes & Microsoft.VisualStudioTools.Project.NativeMethods.FILE_ATTRIBUTE_DIRECTORY) != 0; + if (isDirectory) { + DeleteLongPath(childPath); + } else { + Console.WriteLine("DeleteFile " + childPath); + if (!Microsoft.VisualStudioTools.Project.NativeMethods.DeleteFile(childPath)) { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + } + } while (Microsoft.VisualStudioTools.Project.NativeMethods.FindNextFile(hFind, out wfd)); + + Console.WriteLine("RemoveDirectory " + path); + if (!Microsoft.VisualStudioTools.Project.NativeMethods.RemoveDirectory(path)) { + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + } finally { + Microsoft.VisualStudioTools.Project.NativeMethods.FindClose(hFind); + } + } + + [TestMethod, Priority(0), TestCategory("Core")] + public void GetLongSubPaths() { + string + basePath = CreateTempPathOfLength(248 - 1 - @"\d\d".Length), + shortFile = basePath + @"\f", + shortDir = basePath + @"\d", + shortShortFile = shortDir + @"\f", + shortShortDir = shortDir + @"\d", + shortLongDir = shortDir + @"\dd", + shortLongFile = shortDir + @"\f.ffffffffffffff", + longFile = basePath + @"\f.ffffffffffffff", + longDir = basePath + @"\d.dd", + longLongFile = longDir + @"\ff", + longLongDir = longDir + @"\dd"; + try { + foreach (var path in new[] { shortDir, shortShortDir, shortLongDir, longDir, longLongDir }) { + Console.WriteLine("CreateDirectory {0}", path); + Assert.IsTrue(NativeMethods.CreateDirectory(@"\\?\" + path, IntPtr.Zero), path); + } + + File.WriteAllText(shortFile, ""); + foreach (var path in new[] { shortShortFile, shortLongFile, longFile, longLongFile }) { + Console.WriteLine("CopyFile {0}", path); + Assert.IsTrue(NativeMethods.CopyFile(shortFile, @"\\?\" + path, true), path); + } + + var longPaths = NodejsProjectNode.GetLongSubPaths(basePath).ToList(); + + // Single() acts as assert here (throws if it doesn't find the element matching the condition). + longPaths.Remove(longPaths.Single(lpi => lpi.FullPath == shortLongFile && !lpi.IsDirectory)); + longPaths.Remove(longPaths.Single(lpi => lpi.FullPath == shortLongDir && lpi.IsDirectory)); + longPaths.Remove(longPaths.Single(lpi => lpi.FullPath == longFile && !lpi.IsDirectory)); + longPaths.Remove(longPaths.Single(lpi => lpi.FullPath == longDir && lpi.IsDirectory)); + // longLongFile and longLongDir should not be reported, because their parent longDir is already reported. + + // There should be no other elements reported. + Assert.AreEqual(0, longPaths.Count); + } finally { + DeleteLongPath(basePath); + } + } + + [TestMethod, Priority(0), TestCategory("Core"), TestCategory("Ignore")] + [HostType("VSTestHost")] + public void LongPathCheck() { + string[] expectedLongPaths = { + @"node_modules\azure\node_modules\azure-common\node_modules\xml2js\node_modules\sax\test\trailing-attribute-no-value.js", + @"node_modules\azure\node_modules\azure-common\node_modules\xml2js\node_modules\sax\test\xmlns-xml-default-prefix-attribute.js", + @"node_modules\azure\node_modules\azure-common\node_modules\xml2js\node_modules\sax\test\xmlns-xml-default-redefine.js", + @"node_modules\azure\node_modules\request\node_modules\form-data\node_modules\combined-stream\node_modules", + @"node_modules\azure\node_modules\request\node_modules\http-signature\node_modules\ctype\tst\ctio\uint\tst.roundtrip.js", + }; + + string projectDir = CreateTempPathOfLength(248 - 1 - expectedLongPaths.Min(s => s.Length)); + try { + foreach (var fileName in new[] { "HelloWorld.njsproj", "HelloWorld.sln", "package.json", "README.md", "server.js" }) { + File.Copy(TestData.GetPath(@"TestData\HelloWorld\" + fileName), projectDir + "\\" + fileName); + } + + using (var app = new NodejsVisualStudioApp()) { + try { + NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths = true; + + var project = app.OpenProject(projectDir + "\\HelloWorld.sln"); + + // Wait for new solution to load. + for (int i = 0; i < 40 && app.Dte.Solution.Projects.Count == 0; i++) { + System.Threading.Thread.Sleep(250); + } + + const string interpreterDescription = "Node.js Interactive Window"; + app.Dte.ExecuteCommand("View.Node.jsInteractiveWindow"); + var interactive = app.GetInteractiveWindow(interpreterDescription); + if (interactive == null) { + Assert.Inconclusive("Need " + interpreterDescription); + } + + interactive.WaitForIdleState(); + var npmTask = interactive.ReplWindow.ExecuteCommand(".npm install azure@0.9.12"); + + using (var dialog = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(npmTask)))) { + // The option to offer "npm dedupe" should be there. + var firstCommandLink = dialog.FindByAutomationId("CommandLink_1000"); + Assert.IsNotNull(firstCommandLink); + Assert.IsTrue(firstCommandLink.Current.Name.Contains("npm dedupe")); + + dialog.ClickButtonByAutomationId("ExpandoButton"); + var detailsText = dialog.FindByAutomationId("ExpandedFooterTextLink"); + Assert.IsNotNull(detailsText); + + var reportedLongPaths = + (from line in detailsText.Current.Name.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries) + where line.StartsWith("•") + let nbspIndex = line.IndexOf('\u00A0') + where nbspIndex >= 0 + select line.Substring(1, nbspIndex - 1).Trim() + ).ToArray(); + Console.WriteLine("Reported paths:"); + foreach (var path in reportedLongPaths) { + Console.WriteLine("\t" + path); + } + + reportedLongPaths = reportedLongPaths.Except(expectedLongPaths).ToArray(); + if (reportedLongPaths.Length != 0) { + Console.WriteLine("Unexpected paths:"); + foreach (var path in reportedLongPaths) { + Console.WriteLine("\t" + path); + } + Assert.Fail("Unexpected long paths reported."); + } + + dialog.WaitForClosed(TimeSpan.FromSeconds(1), () => { + // Click the first command button (dedupe). + firstCommandLink.SetFocus(); + Keyboard.Press(System.Windows.Input.Key.Enter); + }); + } + + // Clicking on that button should not change the option. + Assert.IsTrue(NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths); + + interactive.WaitForTextContainsAll("dedupe successfully completed"); + interactive.WaitForIdleState(); + + // npm dedupe won't be able to fix the problem, so we should get the dialog once again. + using (var dialog = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(npmTask)))) { + // The option to offer "npm dedupe" should not be there anymore. + var firstCommandLink = dialog.FindByAutomationId("CommandLink_1000"); + Assert.IsNotNull(firstCommandLink); + Assert.IsFalse(firstCommandLink.Current.Name.Contains("npm dedupe")); + + dialog.WaitForClosed(TimeSpan.FromSeconds(1), () => { + Keyboard.Type("\r"); // click the first command button (do nothing, but warn next time) + }); + } + + npmTask.Wait(1000); + Assert.IsTrue(npmTask.IsCompleted); + + // Clicking on that button should not change the option. + Assert.IsTrue(NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths); + + // Try again to see that the dialog still appears. Any npm command triggers the check. + // and since we didn't do anything to fix the problem, we should still get the dialog. + interactive.WaitForIdleState(); + npmTask = interactive.ReplWindow.ExecuteCommand(".npm list"); + + using (var dialog = new AutomationDialog(app, AutomationElement.FromHandle(app.WaitForDialog(npmTask)))) { + // The option to offer "npm dedupe" should be there again, since this is a new check. + var firstCommandLink = dialog.FindByAutomationId("CommandLink_1000"); + Assert.IsNotNull(firstCommandLink); + Assert.IsTrue(firstCommandLink.Current.Name.Contains("npm dedupe")); + + dialog.WaitForClosed(TimeSpan.FromSeconds(1), () => { + // Click the third command button (do nothing, do not warn anymore) + firstCommandLink.SetFocus(); + Keyboard.Press(System.Windows.Input.Key.Tab); + Keyboard.Press(System.Windows.Input.Key.Tab); + Keyboard.Press(System.Windows.Input.Key.Enter); + }); + } + + npmTask.Wait(1000); + Assert.IsTrue(npmTask.IsCompleted); + + // Clicking on that button should change the option to false. + Assert.IsFalse(NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths); + + // Try again to see that the dialog does not appear anymore. + interactive.WaitForIdleState(); + npmTask = interactive.ReplWindow.ExecuteCommand(".npm list"); + app.WaitForNoDialog(TimeSpan.FromSeconds(3)); + } finally { + NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths = true; + } + } + } finally { + DeleteLongPath(projectDir); + } + } + } +}