Skip to content

Commit

Permalink
Add sane defaults to Start-EditorServices
Browse files Browse the repository at this point in the history
We do not need to require so many CLI flags.

This continues to run the existing Emacs and Vim tests utilizing those
flags as a regression scenario, and adds an additional pair of tests
that launch PSES with a minimal set of flags.
  • Loading branch information
andyleejordan committed Jan 12, 2024
1 parent 4c39342 commit 1b824f1
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 24 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/emacs-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ jobs:
with:
version: '28.2'

- name: Run ERT
- name: Run ERT with full CLI
run: |
emacs -Q --batch -f package-refresh-contents --eval "(package-install 'eglot)"
emacs -Q --batch -l test/emacs-test.el -f ert-run-tests-batch-and-exit
- name: Run ERT with simple CLI
run: |
emacs -Q --batch -f package-refresh-contents --eval "(package-install 'eglot)"
emacs -Q --batch -l test/emacs-simple-test.el -f ert-run-tests-batch-and-exit
7 changes: 6 additions & 1 deletion .github/workflows/vim-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@ jobs:
repository: thinca/vim-themis
path: vim-themis

- name: Run Themis
- name: Run Themis with full CLI
env:
THEMIS_VIM: ${{ steps.vim.outputs.executable }}
run: ./vim-themis/bin/themis ./test/vim-test.vim

- name: Run Themis with simple CLI
env:
THEMIS_VIM: ${{ steps.vim.outputs.executable }}
run: ./vim-themis/bin/themis ./test/vim-simple-test.vim
17 changes: 5 additions & 12 deletions module/PowerShellEditorServices/Start-EditorServices.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,31 @@
#>
[CmdletBinding(DefaultParameterSetName="NamedPipe")]
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]
$HostName,
$HostName = "PSES",

[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]
$HostProfileId,
$HostProfileId = "PSES",

[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]
$HostVersion,
$HostVersion = "0.0.0",

[ValidateNotNullOrEmpty()]
[string]
$BundledModulesPath,

[ValidateNotNullOrEmpty()]
$LogPath,
$LogPath = "PowerShellEditorServices.log",

[ValidateSet("Diagnostic", "Verbose", "Normal", "Warning", "Error")]
$LogLevel,

[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]
$SessionDetailsPath,
$SessionDetailsPath = "PowerShellEditorServices.json",

[switch]
$EnableConsoleRepl,
Expand All @@ -78,9 +74,6 @@ param(
[switch]
$WaitForDebugger,

[switch]
$ConfirmInstall,

[Parameter(ParameterSetName="Stdio", Mandatory=$true)]
[switch]
$Stdio,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,33 +39,44 @@ public StartEditorServicesCommand()
Environment.SetEnvironmentVariable("POWERSHELL_DISTRIBUTION_CHANNEL", "PSES");
_disposableResources = new List<IDisposable>();
_loggerUnsubscribers = new List<IDisposable>();

// These are the actual defaults. Because of how PowerShell cmdlets work, the "defaults"
// in the corresponding .PS1 file don't matter (though they match for discoverability),
// nor can these be set at the field declaration because the engine resets parameters to
// null on invocation.
HostName = "PSES";
HostProfileId = "PSES";
HostVersion = new Version(0, 0, 0);
SessionDetailsPath = "PowerShellEditorServices.json";
LogPath = "PowerShellEditorServices.log";
LogLevel = PsesLogLevel.Normal;
}

/// <summary>
/// The name of the EditorServices host to report.
/// </summary>
[Parameter(Mandatory = true)]
[Parameter]
[ValidateNotNullOrEmpty]
public string HostName { get; set; }

/// <summary>
/// The ID to give to the host's profile.
/// </summary>
[Parameter(Mandatory = true)]
[Parameter]
[ValidateNotNullOrEmpty]
public string HostProfileId { get; set; }

/// <summary>
/// The version to report for the host.
/// </summary>
[Parameter(Mandatory = true)]
[Parameter]
[ValidateNotNullOrEmpty]
public Version HostVersion { get; set; }

/// <summary>
/// Path to the session file to create on startup or startup failure.
/// </summary>
[Parameter(Mandatory = true)]
[Parameter]
[ValidateNotNullOrEmpty]
public string SessionDetailsPath { get; set; }

Expand Down Expand Up @@ -118,7 +129,7 @@ public StartEditorServicesCommand()
/// <summary>
/// The path to where PowerShellEditorServices and its bundled modules are.
/// </summary>
[Parameter]
[Parameter(Mandatory = true)]
[ValidateNotNullOrEmpty]
public string BundledModulesPath { get; set; }

Expand All @@ -133,7 +144,7 @@ public StartEditorServicesCommand()
/// The minimum log level that should be emitted.
/// </summary>
[Parameter]
public PsesLogLevel LogLevel { get; set; } = PsesLogLevel.Normal;
public PsesLogLevel LogLevel { get; set; }

/// <summary>
/// Paths to additional PowerShell modules to be imported at startup.
Expand Down Expand Up @@ -287,9 +298,12 @@ private void StartLogging()

private string GetLogDirPath()
{
string logDir = !string.IsNullOrEmpty(LogPath)
? Path.GetDirectoryName(LogPath)
: Path.GetDirectoryName(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
string logDir = Path.GetDirectoryName(LogPath);
if (string.IsNullOrEmpty(logDir))
{
logDir = Directory.GetCurrentDirectory();
// Path.GetDirectoryName(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
}

// Ensure logDir exists
Directory.CreateDirectory(logDir);
Expand Down
65 changes: 65 additions & 0 deletions test/emacs-simple-test.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
;;; emacs-test.el --- Integration testing script -*- lexical-binding: t; -*-

;; Copyright (c) Microsoft Corporation.
;; Licensed under the MIT License.

;; Author: Andy Jordan <[email protected]>
;; Keywords: PowerShell, LSP

;;; Code:

;; Avoid using old packages.
(setq load-prefer-newer t)

;; Improved TLS Security.
(with-eval-after-load 'gnutls
(custom-set-variables
'(gnutls-verify-error t)
'(gnutls-min-prime-bits 3072)))

;; Package setup.
(require 'package)
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/") t)
(package-initialize)
(package-refresh-contents)

(require 'ert)

(require 'flymake)

(unless (package-installed-p 'powershell)
(package-install 'powershell))
(require 'powershell)

(unless (package-installed-p 'eglot)
(package-install 'eglot))
(require 'eglot)

(ert-deftest powershell-editor-services ()
"Eglot should connect to PowerShell Editor Services."
(let* ((repo (project-root (project-current)))
(start-script (expand-file-name "module/PowerShellEditorServices/Start-EditorServices.ps1" repo))
(module-path (expand-file-name "module" repo))
(test-script (expand-file-name "test/PowerShellEditorServices.Test.Shared/Debugging/VariableTest.ps1" repo))
(eglot-sync-connect t))
(add-to-list
'eglot-server-programs
`(powershell-mode
. ("pwsh" "-NoLogo" "-NoProfile" "-Command" ,start-script
"-BundledModulesPath" ,module-path "-Stdio")))
(with-current-buffer (find-file-noselect test-script)
(should (eq major-mode 'powershell-mode))
(should (apply #'eglot--connect (eglot--guess-contact)))
(should (eglot-current-server))
(let ((lsp (eglot-current-server)))
(should (string= (eglot--project-nickname lsp) "PowerShellEditorServices"))
(should (member (cons 'powershell-mode "powershell") (eglot--languages lsp))))
(sleep-for 5) ; TODO: Wait for "textDocument/publishDiagnostics" instead
(flymake-start)
(goto-char (point-min))
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point))))))

(provide 'emacs-test)
;;; emacs-test.el ends here
41 changes: 41 additions & 0 deletions test/vim-simple-test.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
let s:suite = themis#suite('pses')
let s:assert = themis#helper('assert')

function s:suite.before()
let l:pses_path = g:repo_root . '/module'
let g:LanguageClient_serverCommands = {
\ 'ps1': [ 'pwsh', '-NoLogo', '-NoProfile', '-Command',
\ l:pses_path . '/PowerShellEditorServices/Start-EditorServices.ps1',
\ '-BundledModulesPath', l:pses_path, '-Stdio' ]
\ }
let g:LanguageClient_serverStderr = 'DEBUG'
let g:LanguageClient_loggingFile = g:repo_root . '/LanguageClient.log'
let g:LanguageClient_serverStderr = g:repo_root . '/LanguageServer.log'
endfunction

function s:suite.has_language_client()
call s:assert.includes(&runtimepath, g:repo_root . '/LanguageClient-neovim')
call s:assert.cmd_exists('LanguageClientStart')
call s:assert.not_empty(g:LanguageClient_serverCommands)
call s:assert.true(LanguageClient#HasCommand('ps1'))
endfunction

function s:suite.analyzes_powershell_file()
view test/vim-test.ps1 " This must not use quotes!

let l:bufnr = bufnr('vim-test.ps1$')
call s:assert.not_equal(l:bufnr, -1)
let l:bufinfo = getbufinfo(l:bufnr)[0]

call s:assert.equal(l:bufinfo.name, g:repo_root . '/test/vim-test.ps1')
call s:assert.includes(getbufline(l:bufinfo.name, 1), 'function Do-Work {}')
" TODO: This shouldn't be necessary, vim-ps1 works locally but not in CI.
call setbufvar(l:bufinfo.bufnr, '&filetype', 'ps1')
call s:assert.equal(getbufvar(l:bufinfo.bufnr, '&filetype'), 'ps1')

execute 'LanguageClientStart'
execute 'sleep' 5
call s:assert.equal(getbufvar(l:bufinfo.name, 'LanguageClient_isServerRunning'), 1)
call s:assert.equal(getbufvar(l:bufinfo.name, 'LanguageClient_projectRoot'), g:repo_root)
call s:assert.equal(getbufvar(l:bufinfo.name, 'LanguageClient_statusLineDiagnosticsCounts'), {'E': 0, 'W': 1, 'H': 0, 'I': 0})
endfunction
2 changes: 1 addition & 1 deletion test/vim-test.vim
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ let s:assert = themis#helper('assert')
function s:suite.before()
let l:pses_path = g:repo_root . '/module'
let g:LanguageClient_serverCommands = {
\ 'ps1': ['pwsh', '-NoLogo', '-NoProfile', '-Command',
\ 'ps1': [ 'pwsh', '-NoLogo', '-NoProfile', '-Command',
\ l:pses_path . '/PowerShellEditorServices/Start-EditorServices.ps1',
\ '-HostName', 'vim', '-HostProfileId', 'vim', '-HostVersion', '1.0.0',
\ '-BundledModulesPath', l:pses_path, '-Stdio',
Expand Down

0 comments on commit 1b824f1

Please sign in to comment.