Skip to content

Commit 417cc94

Browse files
authored
Merge pull request #1932 from Fred-Wu/feat/session-aware-plot-viewer
Feat/session aware plot viewer
2 parents 7b5720c + 6a4f2a6 commit 417cc94

64 files changed

Lines changed: 9763 additions & 2063 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/main.yml‎

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ concurrency:
2020

2121
jobs:
2222
test:
23+
env:
24+
VSCR_REQUIRE_PLOT_TESTS: '1'
2325
strategy:
2426
fail-fast: false
2527
matrix:
@@ -43,9 +45,29 @@ jobs:
4345
- name: Verify managed tool consent
4446
run: pnpm run test:tool-consent
4547
- name: Install R test dependencies
46-
run: install.packages(c("remotes", "pkgbuild", "languageserver", "lintr", "styler", "renv"))
48+
uses: r-lib/actions/setup-r-dependencies@f9a764fea8d5c63df6ef9a5c7795bf7deb5d7e05 # v2
49+
with:
50+
working-directory: sess
51+
# Keep Suggests for live plot tests. languageserver brings lintr/styler;
52+
# renv is exercised by the Interactive library-isolation tests.
53+
extra-packages: |
54+
any::remotes
55+
any::pkgbuild
56+
any::languageserver
57+
any::renv
58+
- run: pnpm run compile
59+
- name: Install bundled sess with prepared dependencies
60+
run: remotes::install_local('dist/resources/sess', dependencies = FALSE, upgrade = 'never', force = TRUE)
61+
shell: Rscript {0}
62+
- name: Verify live plot lifecycle dependencies
63+
run: |
64+
packages <- c("processx", "later", "jsonlite", "jgd", "httpgd", "svglite")
65+
for (package in packages) {
66+
message("Loading plot test dependency: ", package)
67+
loadNamespace(package)
68+
}
69+
stopifnot(packageVersion("httpgd") >= "2.0.1")
4770
shell: Rscript {0}
48-
- run: pnpm run build
4971
- name: Verify managed jgd preparation
5072
run: pnpm run test:prepare-jgd
5173
- name: Verify managed rstudioapi preparation
@@ -88,14 +110,20 @@ jobs:
88110
sudo apt-get update
89111
sudo apt-get install -y tmux
90112
VSCR_TEST_TMUX=1 pnpm exec mocha out/test/node/interactiveRuntime.test.js --ui tdd --timeout 60000 --grep "^Interactive real R runtime standalone agent survives its launcher process exiting$"
91-
- name: Run Node tests
113+
- name: Run Node tests including live plot lifecycle tests
92114
run: pnpm run test:node
115+
- name: Run plot lifecycle extension tests (Linux)
116+
if: runner.os == 'Linux'
117+
run: xvfb-run -a pnpm run test:extension --label plot-lifecycle
118+
- name: Run plot lifecycle extension tests
119+
if: runner.os != 'Linux'
120+
run: pnpm run test:extension --label plot-lifecycle
93121
- name: Run extension tests (Linux)
94122
if: runner.os == 'Linux'
95-
run: xvfb-run -a pnpm run test:extension
123+
run: xvfb-run -a pnpm run test:extension --label provider-tests --label editor-command-tests --label interactive-integration
96124
- name: Run extension tests
97125
if: runner.os != 'Linux'
98-
run: pnpm run test:extension
126+
run: pnpm run test:extension --label provider-tests --label editor-command-tests --label interactive-integration
99127
- name: Preserve extension test failure logs
100128
if: failure()
101129
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2

‎.vscode-test.mjs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ export default defineConfig([
3636
mocha: { ...common.mocha, require: './out/test/common/extensionSetup.js' },
3737
launchArgs: testProfile('provider-tests', false)
3838
},
39+
{
40+
...common,
41+
label: 'plot-lifecycle',
42+
files: 'out/test/plot/**/*.test.js',
43+
mocha: { ...common.mocha, require: './out/test/common/extensionSetup.js' },
44+
launchArgs: testProfile('plots', false)
45+
},
3946
{
4047
...common,
4148
label: 'editor-command-tests',

‎R/tests/attach_sess.R‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ writeLines(c(
238238
" sys.source(file.path(getwd(), 'sess', 'R', 'server.R'), scheduler)",
239239
" scheduler$.read_discovery <- function(path) list(endpoint='endpoint-b')",
240240
" scheduler$.configure_discovery_jgd <- function(discovery, enabled) NULL",
241-
" scheduler$runtime_stop <- function() invisible(NULL)",
241+
" scheduler$runtime_stop <- function(preserve_plots=FALSE) invisible(NULL)",
242242
" scheduler$connect <- function(endpoint, ...) {",
243243
" connect_count <<- connect_count + 1L",
244244
" observed[[connect_count]] <<- readLines(reconnect_file, warn=FALSE)",

‎R/tests/prepare-jgd.R‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,20 @@ local({
4646
"jgd <- function() {",
4747
" path <- Sys.getenv('JGD_TEST_DEVICE_LOG', '')",
4848
" if (nzchar(path)) cat('jgd\\n', file=path, append=TRUE)",
49+
# sess now tracks the opened device and attaches its session identity.
50+
# A null PDF supplies a real device without requiring a JGD renderer.
51+
" grDevices::pdf(NULL)",
52+
" invisible(NULL)",
53+
"}",
54+
"jgd_server_info <- function() list(server_info=c(deviceId=as.character(grDevices::dev.cur())))",
55+
"jgd_frame_ext <- function(value) {",
56+
" path <- Sys.getenv('JGD_TEST_DEVICE_LOG', '')",
57+
" if (nzchar(path)) cat(value, '\\n', file=paste0(path, '-frames'), append=TRUE)",
4958
" invisible(NULL)",
5059
"}"
5160
), file.path(package, "R", "api.R"))
52-
writeLines(c("export(fixture_device)", "export(jgd)"), file.path(package, "NAMESPACE"))
61+
writeLines(c("export(fixture_device)", "export(jgd)",
62+
"export(jgd_server_info)", "export(jgd_frame_ext)"), file.path(package, "NAMESPACE"))
5363
previous <- setwd(root)
5464
on.exit(setwd(previous), add = TRUE)
5565
output <- system2_with_child_environment(
@@ -336,6 +346,16 @@ local({
336346
"fixture-jgd-socket-next", "TRUE")))
337347
stopifnot(identical(readLines(file.path(root, "real-approved-real-device"), warn = FALSE),
338348
c("jgd", "jgd")))
349+
frames <- lapply(readLines(file.path(root, "real-approved-real-device-frames"), warn = FALSE),
350+
jsonlite::fromJSON)
351+
stopifnot(length(frames) == 2L)
352+
stopifnot(all(vapply(frames, function(frame) {
353+
identity <- frame$vscodeR
354+
nzchar(identity$sessionId) && nzchar(identity$pid) &&
355+
nzchar(identity$deviceId) && identical(identity$restoring, FALSE)
356+
}, logical(1))))
357+
stopifnot(identical(frames[[1L]]$vscodeR$sessionId, frames[[2L]]$vscodeR$sessionId))
358+
stopifnot(!identical(frames[[1L]]$vscodeR$deviceId, frames[[2L]]$vscodeR$deviceId))
339359

340360
approved_root <- file.path(root, "approved")
341361
dir.create(approved_root)

‎html/httpgd/index.ejs‎

Lines changed: 0 additions & 25 deletions
This file was deleted.

‎html/httpgd/index.ts‎

Lines changed: 0 additions & 238 deletions
This file was deleted.

0 commit comments

Comments
 (0)