galaaz 0.4.10 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/LICENSE +0 -0
  4. data/README.md +3123 -882
  5. data/Rakefile +62 -41
  6. data/bin/galaaz-bootstrap +137 -0
  7. data/bin/galaaz-jruby +14 -0
  8. data/bin/galaaz_jruby_env.inc.sh +6 -0
  9. data/bin/gbookdown +64 -0
  10. data/bin/gknit +223 -6
  11. data/bin/gknit-draft +105 -0
  12. data/bin/gknit-draft.rb +28 -0
  13. data/bin/gknit_Rscript +127 -0
  14. data/bin/grun +27 -1
  15. data/bin/gstudio +49 -4
  16. data/bin/{gstudio.rb → gstudio_irb.rb} +0 -0
  17. data/bin/gstudio_pry.rb +7 -0
  18. data/bin/install-tinytex +6 -0
  19. data/bin/run_all_rspec +43 -0
  20. data/bin/run_example +14 -0
  21. data/bin/run_old_rspec +19 -0
  22. data/bin/run_rspec +23 -0
  23. data/bin/run_rspec_subset +38 -0
  24. data/bin/run_slow_rspec +19 -0
  25. data/blogs/R-on-Rails-Planning-Document.md +940 -0
  26. data/blogs/README.md +100 -0
  27. data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +38 -66
  28. data/blogs/galaaz_ggplot/galaaz_ggplot.log +754 -0
  29. data/blogs/galaaz_ggplot/galaaz_ggplot.md +364 -0
  30. data/blogs/galaaz_ggplot/galaaz_ggplot.tex +607 -0
  31. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/midwest_rb.png +0 -0
  32. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/scatter_plot_rb.png +0 -0
  33. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/midwest_rb.png +0 -0
  34. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/scatter_plot_rb.png +0 -0
  35. data/blogs/galaaz_ggplot/midwest.Rmd +3 -3
  36. data/blogs/galaaz_ggplot/midwest_external_png +0 -0
  37. data/blogs/gknit/gknit.Rmd +52 -55
  38. data/blogs/gknit/gknit.md +94 -94
  39. data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
  40. data/blogs/gknit/gknit_files/figure-html/diverging_bar.png +0 -0
  41. data/blogs/gknit/lst.rds +0 -0
  42. data/blogs/gknit/model.rb +1 -1
  43. data/blogs/gknit/stats.bib +0 -0
  44. data/blogs/manual/include_model_local_repro.Rmd +14 -0
  45. data/blogs/manual/include_model_local_repro.md +75 -0
  46. data/blogs/manual/lst.rds +0 -0
  47. data/blogs/manual/manual.Rmd +1582 -196
  48. data/blogs/manual/manual.log +1786 -0
  49. data/blogs/manual/manual.md +3107 -890
  50. data/blogs/manual/manual.tex +3018 -1086
  51. data/blogs/manual/manual_files/figure-html/bubble-1.png +0 -0
  52. data/blogs/manual/manual_files/figure-html/diverging_bar.png +0 -0
  53. data/blogs/manual/manual_files/figure-latex/bubble-1.png +0 -0
  54. data/blogs/manual/model.rb +41 -0
  55. data/blogs/nse_dplyr/nse_dplyr.Rmd +277 -151
  56. data/blogs/nse_dplyr/nse_dplyr.log +928 -0
  57. data/blogs/nse_dplyr/nse_dplyr.md +457 -293
  58. data/blogs/oh_my/not_so.rb +0 -0
  59. data/blogs/oh_my/oh_my.Rmd +1234 -25
  60. data/blogs/oh_my/oh_my.log +804 -0
  61. data/blogs/oh_my/oh_my.md +1808 -228
  62. data/blogs/oh_my/oh_my.tex +821 -0
  63. data/blogs/oh_my/old.Rmd +15 -14
  64. data/blogs/ruby_plot/ruby_plot.Rmd +58 -82
  65. data/blogs/ruby_plot/ruby_plot.log +885 -0
  66. data/blogs/ruby_plot/ruby_plot.md +71 -103
  67. data/blogs/ruby_plot/ruby_plot.tex +940 -0
  68. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.png +0 -0
  69. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.png +0 -0
  70. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.png +0 -0
  71. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.png +0 -0
  72. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.png +0 -0
  73. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_decorations.png +0 -0
  74. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.png +0 -0
  75. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.png +0 -0
  76. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.png +0 -0
  77. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.png +0 -0
  78. data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.png +0 -0
  79. data/blogs/ruby_plot/ruby_plot_files/figure-latex/dose_len.png +0 -0
  80. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_delivery.png +0 -0
  81. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_dose.png +0 -0
  82. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color.png +0 -0
  83. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color2.png +0 -0
  84. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_decorations.png +0 -0
  85. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_jitter.png +0 -0
  86. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_points.png +0 -0
  87. data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_box_plot.png +0 -0
  88. data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_violin_plot.png +0 -0
  89. data/blogs/ruby_plot/ruby_plot_files/figure-latex/violin_with_jitter.png +0 -0
  90. data/blogs/test/test.Rmd +14 -0
  91. data/examples/50Plots_MasterList/Images/midwest-scatterplot.PNG +0 -0
  92. data/examples/50Plots_MasterList/ScatterPlot.rb +0 -0
  93. data/examples/50Plots_MasterList/scatter_plot.rb +0 -0
  94. data/examples/Bibliography/master.bib +50 -0
  95. data/examples/Bibliography/stats.bib +72 -0
  96. data/examples/R/calc.R +0 -0
  97. data/examples/R/java_interop.R +0 -0
  98. data/examples/bioconductor_deseq2_airway/Documentation/DESeq2-airway-walkthrough.md +56 -0
  99. data/examples/bioconductor_deseq2_airway/bench_galaaz_three_same_process.rb +53 -0
  100. data/examples/bioconductor_deseq2_airway/bench_r_three_same_process.R +34 -0
  101. data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb +33 -0
  102. data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz_optimized.rb +34 -0
  103. data/examples/bioconductor_deseq2_airway/deseq2_airway_minimal.R +30 -0
  104. data/examples/bioconductor_deseq2_airway/deseq2_airway_pipeline_for_bench.R +36 -0
  105. data/examples/islr/all.rb +13 -0
  106. data/examples/islr/ch2.spec.rb +37 -7
  107. data/examples/islr/ch3.spec.rb +11 -2
  108. data/examples/islr/ch3_boston.rb +27 -0
  109. data/examples/islr/ch3_multiple_regression.rb +0 -0
  110. data/examples/islr/ch6.spec.rb +24 -1
  111. data/examples/islr/x_y_rnorm.jpg +0 -0
  112. data/examples/latex_templates/Test-acm_article/Makefile +16 -0
  113. data/examples/latex_templates/Test-acm_article/Test-acm_article.Rmd +65 -0
  114. data/examples/latex_templates/Test-acm_article/acm_proc_article-sp.cls +1670 -0
  115. data/examples/latex_templates/Test-acm_article/sensys-abstract.cls +703 -0
  116. data/examples/latex_templates/Test-acm_article/sigproc.bib +59 -0
  117. data/examples/latex_templates/Test-acs_article/Test-acs_article.Rmd +260 -0
  118. data/examples/latex_templates/Test-acs_article/acs-Test-acs_article.bib +11 -0
  119. data/examples/latex_templates/Test-acs_article/acs-my_output.bib +11 -0
  120. data/examples/latex_templates/Test-acs_article/acstest.bib +17 -0
  121. data/examples/latex_templates/Test-aea_article/AEA.cls +1414 -0
  122. data/{blogs/gknit/marshal.dump → examples/latex_templates/Test-aea_article/BibFile.bib} +0 -0
  123. data/examples/latex_templates/Test-aea_article/Test-aea_article.Rmd +108 -0
  124. data/examples/latex_templates/Test-aea_article/aea.bst +1269 -0
  125. data/examples/latex_templates/Test-aea_article/multicol.sty +853 -0
  126. data/examples/latex_templates/Test-aea_article/references.bib +0 -0
  127. data/examples/latex_templates/Test-aea_article/setspace.sty +546 -0
  128. data/examples/latex_templates/Test-amq_article/Test-amq_article.Rmd +256 -0
  129. data/examples/latex_templates/Test-amq_article/Test-amq_article.pdfsync +3397 -0
  130. data/examples/latex_templates/Test-ams_article/Test-ams_article.Rmd +215 -0
  131. data/examples/latex_templates/Test-ams_article/amstest.bib +436 -0
  132. data/examples/latex_templates/Test-asa_article/Test-asa_article.Rmd +153 -0
  133. data/examples/latex_templates/Test-asa_article/agsm.bst +1353 -0
  134. data/examples/latex_templates/Test-asa_article/bibliography.bib +233 -0
  135. data/examples/latex_templates/Test-ieee_article/IEEEtran.bst +2409 -0
  136. data/examples/latex_templates/Test-ieee_article/IEEEtran.cls +6346 -0
  137. data/examples/latex_templates/Test-ieee_article/Test-ieee_article.Rmd +175 -0
  138. data/examples/latex_templates/Test-ieee_article/mybibfile.bib +20 -0
  139. data/examples/latex_templates/Test-rjournal_article/RJournal.sty +335 -0
  140. data/examples/latex_templates/Test-rjournal_article/RJreferences.bib +18 -0
  141. data/examples/latex_templates/Test-rjournal_article/Test-rjournal_article.Rmd +52 -0
  142. data/examples/latex_templates/Test-springer_article/Test-springer_article.Rmd +65 -0
  143. data/examples/latex_templates/Test-springer_article/bibliography.bib +26 -0
  144. data/examples/latex_templates/Test-springer_article/spbasic.bst +1658 -0
  145. data/examples/latex_templates/Test-springer_article/spmpsci.bst +1512 -0
  146. data/examples/latex_templates/Test-springer_article/spphys.bst +1443 -0
  147. data/examples/latex_templates/Test-springer_article/svglov3.clo +113 -0
  148. data/examples/latex_templates/Test-springer_article/svjour3.cls +1431 -0
  149. data/examples/misc/baseball.csv +0 -0
  150. data/examples/misc/ggplot.rb +3 -2
  151. data/examples/misc/moneyball.rb +0 -0
  152. data/examples/misc/subsetting.rb +0 -0
  153. data/examples/multithread_shards_to_r/shards_to_r.rb +67 -0
  154. data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.Rmd +73 -0
  155. data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.Rmd +382 -0
  156. data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.Rmd +164 -0
  157. data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.Rmd +92 -0
  158. data/examples/rmarkdown/svm-rmarkdown-syllabus-example/attend-grade-relationships.csv +482 -0
  159. data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.Rmd +280 -0
  160. data/examples/rmarkdown/svm-xaringan-example/svm-xaringan-example.Rmd +386 -0
  161. data/examples/sthda_ggplot/README.md +0 -0
  162. data/examples/sthda_ggplot/RUN.md +41 -0
  163. data/examples/sthda_ggplot/all.rb +0 -0
  164. data/examples/sthda_ggplot/one_variable_continuous/density_gg.rb +0 -0
  165. data/examples/sthda_ggplot/one_variable_continuous/geom_area.rb +0 -0
  166. data/examples/sthda_ggplot/one_variable_continuous/geom_density.rb +2 -0
  167. data/examples/sthda_ggplot/one_variable_continuous/geom_dotplot.rb +0 -0
  168. data/examples/sthda_ggplot/one_variable_continuous/geom_freqpoly.rb +0 -0
  169. data/examples/sthda_ggplot/one_variable_continuous/geom_histogram.rb +0 -0
  170. data/examples/sthda_ggplot/one_variable_continuous/histogram_density.rb +0 -0
  171. data/examples/sthda_ggplot/one_variable_continuous/stat.rb +0 -0
  172. data/examples/sthda_ggplot/one_variable_discrete/bar.rb +0 -0
  173. data/examples/sthda_ggplot/qplots/box_violin_dot.rb +0 -0
  174. data/examples/sthda_ggplot/qplots/scatter_plots.rb +0 -0
  175. data/examples/sthda_ggplot/scatter_gg.rb +0 -0
  176. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_bin2d.rb +0 -0
  177. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_density2d.rb +0 -0
  178. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_hex.rb +0 -0
  179. data/examples/sthda_ggplot/two_variables_cont_cont/geom_point.rb +0 -0
  180. data/examples/sthda_ggplot/two_variables_cont_cont/geom_smooth.rb +0 -0
  181. data/examples/sthda_ggplot/two_variables_cont_cont/misc.rb +0 -0
  182. data/examples/sthda_ggplot/two_variables_cont_function/geom_area.rb +4 -3
  183. data/examples/sthda_ggplot/two_variables_disc_cont/geom_bar.rb +0 -0
  184. data/examples/sthda_ggplot/two_variables_disc_cont/geom_boxplot.rb +0 -0
  185. data/examples/sthda_ggplot/two_variables_disc_cont/geom_dotplot.rb +0 -0
  186. data/examples/sthda_ggplot/two_variables_disc_cont/geom_jitter.rb +0 -0
  187. data/examples/sthda_ggplot/two_variables_disc_cont/geom_line.rb +0 -0
  188. data/examples/sthda_ggplot/two_variables_disc_cont/geom_violin.rb +0 -0
  189. data/examples/sthda_ggplot/two_variables_disc_disc/geom_jitter.rb +0 -0
  190. data/examples/sthda_ggplot/two_variables_error/geom_crossbar.rb +0 -0
  191. data/ext/new_bridge/Makefile +46 -0
  192. data/ext/new_bridge/galaaz_gatekeeper_phase0.cpp +12 -0
  193. data/ext/new_bridge/galaaz_gatekeeper_phase1.cpp +1639 -0
  194. data/lib/R_interface/galaaz_device.R +20 -0
  195. data/lib/R_interface/include_engine.R +109 -0
  196. data/lib/R_interface/new_bridge_adapter.rb +824 -0
  197. data/lib/R_interface/r.rb +177 -25
  198. data/lib/R_interface/r_arrow.rb +113 -0
  199. data/lib/R_interface/r_libs.R +4 -4
  200. data/lib/R_interface/r_methods.rb +13 -116
  201. data/lib/R_interface/r_module_s.rb +0 -0
  202. data/lib/R_interface/rbinary_operators.rb +20 -2
  203. data/lib/R_interface/rclosure.rb +5 -1
  204. data/lib/R_interface/rdata_frame.rb +34 -70
  205. data/lib/R_interface/rdevice.rb +125 -0
  206. data/lib/R_interface/rdevices.R +0 -0
  207. data/lib/R_interface/renvironment.rb +10 -4
  208. data/lib/R_interface/rexpression.rb +5 -1
  209. data/lib/R_interface/rindexed_object.rb +41 -13
  210. data/lib/R_interface/rlanguage.rb +20 -62
  211. data/lib/R_interface/rlist.rb +115 -25
  212. data/lib/R_interface/rlogical_operators.rb +0 -0
  213. data/lib/R_interface/rmatrix.rb +2 -11
  214. data/lib/R_interface/rmd_indexed_object.rb +5 -1
  215. data/lib/R_interface/robject.rb +348 -290
  216. data/lib/R_interface/rpkg.rb +1 -0
  217. data/lib/R_interface/rsupport.rb +610 -331
  218. data/lib/R_interface/rsupport_scope.rb +2 -1
  219. data/lib/R_interface/rsymbol.rb +50 -0
  220. data/lib/R_interface/ruby_callback.rb +2 -3
  221. data/lib/R_interface/ruby_extensions.rb +225 -175
  222. data/lib/R_interface/runary_operators.rb +0 -0
  223. data/lib/R_interface/rvector.rb +147 -31
  224. data/lib/galaaz.rb +0 -0
  225. data/lib/galaaz_jruby.rb +22 -0
  226. data/lib/gknit/diagnostics.rb +50 -0
  227. data/lib/gknit/draft.rb +111 -0
  228. data/lib/gknit/include_engine.rb +15 -7
  229. data/lib/gknit/knitr_engine.rb +223 -107
  230. data/lib/gknit/rb_engine.rb +3 -3
  231. data/lib/gknit/ruby_engine.rb +0 -0
  232. data/lib/gknit.rb +3 -0
  233. data/lib/new_bridge/bootstrap/windows_bootstrap.rb +285 -0
  234. data/lib/new_bridge/envelope.rb +51 -0
  235. data/lib/new_bridge/eval_result.rb +26 -0
  236. data/lib/new_bridge/framing.rb +39 -0
  237. data/lib/new_bridge/instance_pool_client.rb +38 -0
  238. data/lib/new_bridge/r_instance_manager.rb +404 -0
  239. data/lib/new_bridge/session_client.rb +530 -0
  240. data/lib/new_bridge/tcp_framed.rb +44 -0
  241. data/lib/new_bridge.rb +9 -0
  242. data/lib/util/exec_ruby.rb +95 -46
  243. data/lib/util/inline_file.rb +35 -30
  244. data/new_bridge_specs/benchmark_phase5_5_unboxing_spec.rb +96 -0
  245. data/new_bridge_specs/eval_r_async_spec.rb +113 -0
  246. data/new_bridge_specs/integration_phase5_1_concurrent_spec.rb +50 -0
  247. data/new_bridge_specs/integration_phase5_1_eval_spec.rb +16 -0
  248. data/new_bridge_specs/integration_phase5_1_r_api_spec.rb +25 -0
  249. data/new_bridge_specs/integration_phase5_1_smoke_spec.rb +31 -0
  250. data/new_bridge_specs/integration_phase5_2_dataframe_unboxing_spec.rb +19 -0
  251. data/new_bridge_specs/integration_phase5_2_handle_eval_unboxing_spec.rb +25 -0
  252. data/new_bridge_specs/integration_phase5_3_callback_args_spec.rb +28 -0
  253. data/new_bridge_specs/integration_phase5_3_callback_error_spec.rb +22 -0
  254. data/new_bridge_specs/integration_phase5_3_callback_timeout_spec.rb +28 -0
  255. data/new_bridge_specs/integration_phase5_3_callbacks_smoke_spec.rb +22 -0
  256. data/new_bridge_specs/integration_phase5_3_edge_cases_spec.rb +52 -0
  257. data/new_bridge_specs/integration_phase5_3_nested_spec.rb +30 -0
  258. data/new_bridge_specs/integration_phase5_4_concurrent_sessions_spec.rb +53 -0
  259. data/new_bridge_specs/integration_phase5_4_nested_session_callbacks_spec.rb +49 -0
  260. data/new_bridge_specs/integration_phase5_4_session_routing_spec.rb +38 -0
  261. data/new_bridge_specs/integration_phase5_5_stress_concurrency_spec.rb +52 -0
  262. data/new_bridge_specs/integration_phase5_5_unbox_walk_spec.rb +46 -0
  263. data/new_bridge_specs/phase0_protocol_spec.rb +96 -0
  264. data/new_bridge_specs/phase1_req_ret_spec.rb +66 -0
  265. data/new_bridge_specs/phase2_multi_instance_spec.rb +67 -0
  266. data/new_bridge_specs/phase3_callbacks_spec.rb +71 -0
  267. data/new_bridge_specs/phase4_2_hardening_spec.rb +252 -0
  268. data/new_bridge_specs/phase4_3_r_instance_manager_spec.rb +85 -0
  269. data/new_bridge_specs/phase4_nested_callbacks_spec.rb +123 -0
  270. data/r_requires/ggplot.rb +0 -0
  271. data/r_requires/knitr.rb +0 -0
  272. data/specs/all.rb +15 -11
  273. data/specs/arrow_from_ruby_batches_spec.rb +50 -0
  274. data/specs/arrow_semantics_spec.rb +64 -0
  275. data/specs/bridge_concurrent_spec.rb +46 -0
  276. data/specs/bridge_nested_spec.rb +25 -0
  277. data/specs/dataframe_semantics_spec.rb +122 -0
  278. data/specs/dataframe_single_index_logical_filter_spec.rb +21 -0
  279. data/specs/dispatch_probe_cache_spec.rb +38 -0
  280. data/specs/dispatch_probe_error_class_fallback_spec.rb +20 -0
  281. data/specs/dispatch_probe_fallback_spec.rb +18 -0
  282. data/specs/environment_semantics_spec.rb +89 -0
  283. data/specs/field_access_spec.rb +31 -0
  284. data/specs/figures/bg.jpeg +0 -0
  285. data/specs/figures/bg.png +0 -0
  286. data/specs/figures/bg.svg +168 -57
  287. data/specs/figures/dose_len.png +0 -0
  288. data/specs/figures/no_args.jpeg +0 -0
  289. data/specs/figures/no_args.png +0 -0
  290. data/specs/figures/no_args.svg +168 -57
  291. data/specs/figures/width_height.jpeg +0 -0
  292. data/specs/figures/width_height.png +0 -0
  293. data/specs/figures/width_height_units1.jpeg +0 -0
  294. data/specs/figures/width_height_units1.png +0 -0
  295. data/specs/figures/width_height_units2.jpeg +0 -0
  296. data/specs/figures/width_height_units2.png +0 -0
  297. data/specs/formula_semantics_spec.rb +81 -0
  298. data/specs/galaaz_util_exec_ruby_spec.rb +85 -0
  299. data/specs/galaaz_util_inline_file_spec.rb +54 -0
  300. data/specs/gknit_cli_option_permutation_spec.rb +24 -0
  301. data/specs/gknit_include_engine_spec.rb +72 -0
  302. data/specs/gknit_install_timeout_report_spec.rb +69 -0
  303. data/specs/gknit_internal_error_report_spec.rb +57 -0
  304. data/specs/gknit_vector_map_output_spec.rb +59 -0
  305. data/specs/globalenv_guardrail_spec.rb +52 -0
  306. data/specs/language_expression_semantics_spec.rb +145 -0
  307. data/specs/list_semantics_spec.rb +111 -0
  308. data/specs/new_bridge_bulk_dataframe_transfer_spec.rb +44 -0
  309. data/specs/new_bridge_bulk_vector_transfer_spec.rb +73 -0
  310. data/specs/new_bridge_callback_timeout_spec.rb +69 -0
  311. data/specs/new_bridge_eval_r_fallback_spec.rb +55 -0
  312. data/specs/nil_null_spec.rb +42 -0
  313. data/specs/object_build_phase2_spec.rb +53 -0
  314. data/specs/phase1_callback_bridge_spec.rb +84 -0
  315. data/specs/phase2_gknit_generic_rendering_guardrail_spec.rb +46 -0
  316. data/specs/phase2_gknit_no_raw_code_leakage_spec.rb +43 -0
  317. data/specs/phase3_gknit_generic_graphics_capture_spec.rb +71 -0
  318. data/specs/plot_device_semantics_spec.rb +28 -0
  319. data/specs/plot_snapshot_semantics_spec.rb +58 -0
  320. data/specs/protocol_result_spec.rb +236 -0
  321. data/specs/r_batch_fail_fast_spec.rb +47 -0
  322. data/specs/r_bridge_bootstrap_spec.rb +11 -0
  323. data/specs/r_devices.spec.rb +1 -1
  324. data/specs/r_eval.spec.rb +16 -18
  325. data/specs/r_function.spec.rb +1 -1
  326. data/specs/r_instance_manager_spec.rb +285 -0
  327. data/specs/r_list_apply.spec.rb +15 -15
  328. data/specs/r_matrix.spec.rb +0 -0
  329. data/specs/r_nse.spec.rb +5 -5
  330. data/specs/r_object_send_dispatch_spec.rb +13 -0
  331. data/specs/r_vector_comparator_spec.rb +8 -0
  332. data/specs/r_vector_creation.spec.rb +0 -0
  333. data/specs/r_vector_functions.spec.rb +0 -0
  334. data/specs/r_vector_object.spec.rb +0 -0
  335. data/specs/r_vector_operators.spec.rb +0 -0
  336. data/specs/r_vector_structured_scalar_reads_spec.rb +35 -0
  337. data/specs/r_vector_subsetting.spec.rb +0 -0
  338. data/specs/range_helper_spec.rb +21 -0
  339. data/specs/rsupport_scope_spec.rb +28 -0
  340. data/specs/rsupport_var_name_thread_safety_spec.rb +24 -0
  341. data/specs/scalar_character_spec.rb +44 -0
  342. data/specs/scoped_symbol_dsl_refinement_spec.rb +40 -0
  343. data/specs/session_env_bridge_spec.rb +25 -0
  344. data/specs/simplecov_bootstrap_spec.rb +10 -0
  345. data/specs/spec_helper.rb +10 -0
  346. data/specs/tmp.rb +41 -20
  347. data/specs/unboxing_recursion_regression_spec.rb +30 -0
  348. data/specs/unboxing_spec.rb +49 -0
  349. data/specs/verify_callbacks.rb +42 -0
  350. data/sty/galaaz.sty +0 -0
  351. data/version.rb +1 -1
  352. metadata +239 -71
  353. data/blogs/galaaz_ggplot/galaaz_ggplot.aux +0 -41
  354. data/blogs/galaaz_ggplot/galaaz_ggplot.html +0 -705
  355. data/blogs/galaaz_ggplot/galaaz_ggplot.out +0 -10
  356. data/blogs/galaaz_ggplot/galaaz_ggplot.pdf +0 -0
  357. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-latex/midwest_rb.pdf +0 -0
  358. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-latex/scatter_plot_rb.pdf +0 -0
  359. data/blogs/galaaz_ggplot/midwest.html +0 -188
  360. data/blogs/gknit/gknit.html +0 -2266
  361. data/blogs/gknit/gknit.pdf +0 -0
  362. data/blogs/gknit/gknit.tex +0 -1358
  363. data/blogs/manual/graph.rb +0 -29
  364. data/blogs/manual/manual.html +0 -2995
  365. data/blogs/manual/manual.pdf +0 -0
  366. data/blogs/manual/manual_files/figure-latex/diverging_bar.pdf +0 -0
  367. data/blogs/nse_dplyr/nse_dplyr.html +0 -960
  368. data/blogs/nse_dplyr/nse_dplyr.pdf +0 -0
  369. data/blogs/nse_dplyr/nse_dplyr.tex +0 -1373
  370. data/blogs/oh_my/oh_my.html +0 -680
  371. data/blogs/ruby_plot/ruby_plot.Rmd_external_figs +0 -662
  372. data/blogs/ruby_plot/ruby_plot.html +0 -729
  373. data/blogs/ruby_plot/ruby_plot.pdf +0 -0
  374. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.svg +0 -57
  375. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.svg +0 -106
  376. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.svg +0 -110
  377. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.svg +0 -174
  378. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.svg +0 -236
  379. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.svg +0 -296
  380. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.svg +0 -236
  381. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.svg +0 -218
  382. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.svg +0 -128
  383. data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.svg +0 -150
  384. data/examples/paper/paper.rb +0 -36
  385. data/specs/r_dataframe.spec.rb +0 -379
  386. data/specs/r_environment.spec.rb +0 -140
  387. data/specs/r_formula.spec.rb +0 -232
  388. data/specs/r_language.spec.rb +0 -112
  389. data/specs/r_list.spec.rb +0 -293
  390. data/specs/r_plots.spec.rb +0 -72
  391. data/specs/ruby_expression.spec.rb +0 -315
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'galaaz'
4
+
5
+ describe 'Formula semantics' do
6
+ context 'formula construction' do
7
+ it 'builds formulas from string and DSL' do
8
+ f1 = R.formula('mpg ~ wt + cyl')
9
+ expect(f1.to_s.lines.first.chomp).to eq('mpg ~ wt + cyl')
10
+
11
+ f2 = R[:mpg].til R[:wt] + R[:cyl]
12
+ expect(f2.to_s.lines.first.chomp).to eq('mpg ~ wt + cyl')
13
+ end
14
+
15
+ it 'builds interaction formulas with operators' do
16
+ f1 = R[:y].til R[:x] * R[:x2]
17
+ expect(f1.to_s.lines.first.chomp).to eq('y ~ x * x2')
18
+
19
+ f2 = R[:y].til R[:x] + R[:x2] + (R[:x].inter R[:x2])
20
+ expect(f2.to_s.lines.first.chomp).to eq('y ~ x + x2 + x:x2')
21
+
22
+ f3 = R[:y].til R[:a] + (R[:b]._ :in, R[:a])
23
+ expect(f3.to_s.lines.first.chomp).to eq('y ~ a + b %in% a')
24
+ end
25
+
26
+ it 'builds formulas using dot and one-sided forms' do
27
+ rhs_dot = R[:supp].til R[:__]
28
+ expect(rhs_dot.to_s.lines.first.chomp).to eq('supp ~ .')
29
+ expect(rhs_dot.rclass).to eq('formula')
30
+
31
+ lhs_dot = R[:__].til R[:supp]
32
+ expect(lhs_dot.to_s.lines.first.chomp).to eq('. ~ supp')
33
+ expect(lhs_dot.rclass).to eq('formula')
34
+
35
+ one_sided = R[:all].til R[:supp]
36
+ expect(one_sided.to_s.lines.first.chomp).to eq('~supp')
37
+ expect(one_sided.rclass).to eq('formula')
38
+ end
39
+
40
+ it 'builds conditional and function-lhs formulas' do
41
+ cond = R[:Sepal__Width].til R[:Petal__Width] | R[:Species]
42
+ expect(cond.to_s.lines.first.chomp).to eq('Sepal.Width ~ Petal.Width | Species')
43
+
44
+ lhs_fun = E.log(:y).til R[:a] + E.log(:x)
45
+ expect(lhs_fun.to_s.lines.first.chomp).to eq('log(y) ~ a + log(x)')
46
+ end
47
+
48
+ it "builds subtraction operator formula terms" do
49
+ f = R[:y].til R[:x1] - R[:x2]
50
+ expect(f.to_s.lines.first.chomp).to eq('y ~ x1 - x2')
51
+ end
52
+ end
53
+
54
+ context 'model.frame and lm with formula' do
55
+ it 'builds model frame with deterministic values under set.seed' do
56
+ R.set__seed(123)
57
+ x = R.rnorm(5)
58
+ x2 = R.rnorm(5)
59
+ y = R.rnorm(5)
60
+
61
+ formula = R[:y].til R[:x] * R[:x2]
62
+ model = R.model__frame(formula, data: R.data__frame(x: x, y: y, x2: x2))
63
+
64
+ expect((model[1, 1] >> 0)).to be_within(1e-9).of(1.2240817974394615)
65
+ expect((model[1, 3] >> 0)).to be_within(1e-9).of(1.715064986883281)
66
+ expect((model[3, 2] >> 0)).to be_within(1e-9).of(1.558708314149124)
67
+ expect((model[5, 1] >> 0)).to be_within(1e-9).of(-0.5558411347540749)
68
+ end
69
+
70
+ it 'fits lm on mtcars and predicts expected trend values' do
71
+ fit = R.lm((R[:mpg].til R[:wt] + R[:cyl]), data: :mtcars)
72
+ expect((fit.coefficients[[1]] >> 0)).to be_within(1e-9).of(39.68626148025295)
73
+ expect((fit.coefficients[['wt']] >> 0)).to be_within(1e-9).of(-3.190972138983746)
74
+ expect((fit.coefficients[['cyl']] >> 0)).to be_within(1e-9).of(-1.507794968259798)
75
+
76
+ pred = R.predict(fit, R.data__frame(wt: R.c(3.0, 2.0), cyl: R.c(6.0, 4.0)))
77
+ expect((pred[1] >> 0)).to be_within(1e-9).of(21.066575253742926)
78
+ expect((pred[2] >> 0)).to be_within(1e-9).of(27.273137329246268)
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'galaaz'
4
+
5
+ describe GalaazUtil do
6
+ describe RC do
7
+ it 'normalizes R objects and arrays recursively for output' do
8
+ rc = RC.new
9
+ vec = R.c(1, 2, 3)
10
+ normalized = rc.normalize_output_arg([vec, 'x', [vec]])
11
+ expect(normalized[0]).to eq(vec.to_s)
12
+ expect(normalized[1]).to eq('x')
13
+ expect(normalized[2][0]).to eq(vec.to_s)
14
+ end
15
+
16
+ it 'tracks outputs and resets output list' do
17
+ rc = RC.new
18
+ rc.outputs('a')
19
+ expect(rc.out_list).to be_a(R::List).or be_a(R::Vector)
20
+ rc.reset_outputs
21
+ expect(rc.out_list).to eq(nil)
22
+ expect(rc.get_binding).to be_a(Binding)
23
+ end
24
+ end
25
+
26
+ describe '.knitr_logical_trueish?' do
27
+ let(:wrapper) do
28
+ Struct.new(:value) do
29
+ def unboxed_get(_idx)
30
+ value
31
+ end
32
+ end
33
+ end
34
+
35
+ it 'treats nil and NA-like wrappers as true by default' do
36
+ expect(GalaazUtil.knitr_logical_trueish?(nil)).to eq(true)
37
+ expect(GalaazUtil.knitr_logical_trueish?(wrapper.new(nil))).to eq(true)
38
+ end
39
+
40
+ it 'handles booleans and numerics from wrappers' do
41
+ expect(GalaazUtil.knitr_logical_trueish?(wrapper.new(true))).to eq(true)
42
+ expect(GalaazUtil.knitr_logical_trueish?(wrapper.new(false))).to eq(false)
43
+ expect(GalaazUtil.knitr_logical_trueish?(wrapper.new(0))).to eq(false)
44
+ expect(GalaazUtil.knitr_logical_trueish?(wrapper.new(2))).to eq(true)
45
+ end
46
+
47
+ it 'handles string-like values from wrappers' do
48
+ expect(GalaazUtil.knitr_logical_trueish?(wrapper.new('FALSE'))).to eq(false)
49
+ expect(GalaazUtil.knitr_logical_trueish?(wrapper.new('true'))).to eq(true)
50
+ end
51
+ end
52
+
53
+ describe '.knitr_option_trueish?' do
54
+ let(:bridge) { instance_double('Bridge') }
55
+ let(:options) { Struct.new(:r_interop).new('g2_v_opts') }
56
+
57
+ before do
58
+ allow(R).to receive(:bridge).and_return(bridge)
59
+ end
60
+
61
+ it 'returns default when options are not interop-like' do
62
+ expect(GalaazUtil.knitr_option_trueish?(nil, 'echo', default: false)).to eq(false)
63
+ expect(GalaazUtil.knitr_option_trueish?(Object.new, 'echo', default: true)).to eq(true)
64
+ end
65
+
66
+ it 'parses TRUE/FALSE and numeric tokens from R output' do
67
+ allow(bridge).to receive(:eval_r).and_return('[1] "TRUE"', '[1] "FALSE"', '[1] "0"', '[1] "3"')
68
+ expect(GalaazUtil.knitr_option_trueish?(options, 'echo', default: false)).to eq(true)
69
+ expect(GalaazUtil.knitr_option_trueish?(options, 'echo', default: true)).to eq(false)
70
+ expect(GalaazUtil.knitr_option_trueish?(options, 'echo', default: true)).to eq(false)
71
+ expect(GalaazUtil.knitr_option_trueish?(options, 'echo', default: false)).to eq(true)
72
+ end
73
+
74
+ it 'falls back to default for NA/NULL/empty or bridge errors' do
75
+ allow(bridge).to receive(:eval_r).and_return('[1] "NA"', '[1] "NULL"', '')
76
+ expect(GalaazUtil.knitr_option_trueish?(options, 'echo', default: false)).to eq(false)
77
+ expect(GalaazUtil.knitr_option_trueish?(options, 'echo', default: true)).to eq(true)
78
+ expect(GalaazUtil.knitr_option_trueish?(options, 'echo', default: false)).to eq(false)
79
+
80
+ allow(bridge).to receive(:eval_r).and_raise(StandardError, 'bridge down')
81
+ expect(GalaazUtil.knitr_option_trueish?(options, 'echo', default: true)).to eq(true)
82
+ end
83
+ end
84
+ end
85
+
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tmpdir'
4
+ require 'fileutils'
5
+ require 'galaaz'
6
+
7
+ describe GalaazUtil do
8
+ describe '.inline_file_path' do
9
+ it 'resolves a local .rb file when relative is true' do
10
+ Dir.mktmpdir('galaaz_inline_local') do |dir|
11
+ file = File.join(dir, 'snippet.rb')
12
+ File.write(file, "puts 'ok'\n")
13
+
14
+ path = GalaazUtil.inline_file_path('snippet', true, dir)
15
+ expect(path).to eq(file)
16
+ end
17
+ end
18
+
19
+ it 'resolves from load path when relative is false' do
20
+ Dir.mktmpdir('galaaz_inline_loadpath') do |dir|
21
+ file = File.join(dir, 'from_load_path.rb')
22
+ File.write(file, "puts 'loadpath'\n")
23
+
24
+ begin
25
+ $LOAD_PATH.unshift(dir)
26
+ path = GalaazUtil.inline_file_path('from_load_path', false, '/tmp')
27
+ expect(path).to eq(file)
28
+ ensure
29
+ $LOAD_PATH.delete(dir)
30
+ end
31
+ end
32
+ end
33
+
34
+ it 'raises when file cannot be found' do
35
+ expect do
36
+ GalaazUtil.inline_file_path('definitely_missing_file_abc_xyz', false, '/tmp')
37
+ end.to raise_error(Errno::ENOENT)
38
+ end
39
+ end
40
+
41
+ describe '.inline_file' do
42
+ it 'returns full file contents' do
43
+ Dir.mktmpdir('galaaz_inline_read') do |dir|
44
+ file = File.join(dir, 'content.rb')
45
+ body = "a = 1\nb = 2\nputs a + b\n"
46
+ File.write(file, body)
47
+
48
+ code = GalaazUtil.inline_file('content', true, dir)
49
+ expect(code).to eq(body)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+
5
+ describe 'gknit CLI option parsing' do
6
+ it 'accepts options when they appear before filename' do
7
+ stdout, stderr, status = Open3.capture3(
8
+ 'ruby', 'bin/gknit', '--callback_timeout_ms', 'not_an_integer', 'specs/does_not_exist.Rmd'
9
+ )
10
+
11
+ expect(status.success?).to eq(false)
12
+ expect("#{stdout}\n#{stderr}").to include('invalid argument: --callback_timeout_ms')
13
+ end
14
+
15
+ it 'accepts options when they appear after filename' do
16
+ stdout, stderr, status = Open3.capture3(
17
+ 'ruby', 'bin/gknit', 'specs/does_not_exist.Rmd',
18
+ '--callback_timeout_ms', 'not_an_integer'
19
+ )
20
+
21
+ expect(status.success?).to eq(false)
22
+ expect("#{stdout}\n#{stderr}").to include('invalid argument: --callback_timeout_ms')
23
+ end
24
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'open3'
5
+ require 'tmpdir'
6
+
7
+ describe 'gknit include engine' do
8
+ def self.gknit_env
9
+ home = Dir.home
10
+ extra = [
11
+ File.join(home, 'bin'),
12
+ File.join(home, '.TinyTeX', 'bin')
13
+ ].select { |dir| File.directory?(dir) }
14
+ path = ENV.fetch('PATH', '')
15
+ path = ([*extra, path].join(File::PATH_SEPARATOR)) unless extra.empty?
16
+ {
17
+ 'JAVA_OPTS' => '--add-opens=java.base/java.nio=ALL-UNNAMED',
18
+ 'PATH' => path
19
+ }
20
+ end
21
+
22
+ it 'loads include file code so constants are available in following ruby chunks' do
23
+ root = File.expand_path('..', __dir__)
24
+ workdir = Dir.mktmpdir('gknit_include_engine_', root)
25
+
26
+ begin
27
+ model_rb = File.join(workdir, 'model.rb')
28
+ File.write(model_rb, <<~RUBY)
29
+ class Model
30
+ def answer
31
+ 42
32
+ end
33
+ end
34
+ RUBY
35
+
36
+ rmd_path = File.join(workdir, 'include_model.Rmd')
37
+ File.write(rmd_path, <<~RMD)
38
+ ---
39
+ title: "include engine spec"
40
+ output:
41
+ github_document: default
42
+ ---
43
+
44
+ ```{include model}
45
+ ```
46
+
47
+ ```{ruby, echo=FALSE}
48
+ m = Model.new
49
+ puts m.answer
50
+ ```
51
+ RMD
52
+
53
+ rel_rmd = File.basename(workdir) + '/' + File.basename(rmd_path)
54
+ out, err, st = Open3.capture3(
55
+ self.class.gknit_env,
56
+ 'bin/gknit', '--output_format', 'github_document', rel_rmd,
57
+ chdir: root
58
+ )
59
+ expect(st.success?).to be(true), "gknit failed\nstdout:\n#{out}\nstderr:\n#{err}"
60
+
61
+ md_path = rmd_path.sub(/\.Rmd\z/, '.md')
62
+ expect(File.exist?(md_path)).to be(true), "missing markdown output: #{md_path}"
63
+ md = File.read(md_path)
64
+
65
+ expect(md).to include('42')
66
+ expect(md).not_to include('uninitialized constant RC::Model')
67
+ expect(md).not_to include('Include failed:')
68
+ ensure
69
+ FileUtils.rm_rf(workdir) if workdir && File.directory?(workdir)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'open3'
5
+ require 'tmpdir'
6
+
7
+ describe 'gknit install timeout reporting' do
8
+ def self.gknit_env
9
+ home = Dir.home
10
+ extra = [
11
+ File.join(home, 'bin'),
12
+ File.join(home, '.TinyTeX', 'bin')
13
+ ].select { |dir| File.directory?(dir) }
14
+ path = ENV.fetch('PATH', '')
15
+ path = ([*extra, path].join(File::PATH_SEPARATOR)) unless extra.empty?
16
+ {
17
+ 'JAVA_OPTS' => '--add-opens=java.base/java.nio=ALL-UNNAMED',
18
+ 'PATH' => path
19
+ }
20
+ end
21
+
22
+ it 'continues processing and prints timeout in final report' do
23
+ skip('Temporarily skipped: installation timeout behavior will be reviewed in a dedicated pass')
24
+ root = File.expand_path('..', __dir__)
25
+ workdir = Dir.mktmpdir('gknit_install_timeout_', root)
26
+
27
+ begin
28
+ rmd_path = File.join(workdir, 'install_timeout.Rmd')
29
+ File.write(rmd_path, <<~RMD)
30
+ ---
31
+ title: "install timeout"
32
+ output:
33
+ github_document: default
34
+ ---
35
+
36
+ ```{ruby setup_stub}
37
+ R.bridge.eval_r("install.packages <- function(...) { Sys.sleep(2); invisible(NULL) }")
38
+ ```
39
+
40
+ ```{ruby timeout_install}
41
+ R.install_and_loads('definitely_fake_pkg_for_timeout_spec')
42
+ ```
43
+
44
+ ```{ruby after_timeout}
45
+ puts "AFTER_TIMEOUT_CHUNK_OK"
46
+ ```
47
+ RMD
48
+
49
+ rel_rmd = File.basename(workdir) + '/' + File.basename(rmd_path)
50
+ out, err, st = Open3.capture3(
51
+ self.class.gknit_env,
52
+ 'bin/gknit', '--output_format', 'github_document', '--bridge_timeout_sec', '1', rel_rmd,
53
+ chdir: root
54
+ )
55
+
56
+ md_path = File.join(workdir, 'install_timeout.md')
57
+ expect(st.success?).to be(true)
58
+ expect(File.exist?(md_path)).to be(true)
59
+ md = File.read(md_path)
60
+ expect(md).to include('AFTER_TIMEOUT_CHUNK_OK')
61
+ expect(err).to include('gknit internal errors detected:')
62
+ expect(err).to include('chunk=timeout_install')
63
+ expect(err).to include('no RET for')
64
+ expect(out).not_to be_nil
65
+ ensure
66
+ FileUtils.rm_rf(workdir) if workdir && File.directory?(workdir)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'open3'
5
+ require 'tmpdir'
6
+
7
+ describe 'gknit internal error report' do
8
+ def self.gknit_env
9
+ home = Dir.home
10
+ extra = [
11
+ File.join(home, 'bin'),
12
+ File.join(home, '.TinyTeX', 'bin')
13
+ ].select { |dir| File.directory?(dir) }
14
+ path = ENV.fetch('PATH', '')
15
+ path = ([*extra, path].join(File::PATH_SEPARATOR)) unless extra.empty?
16
+ {
17
+ 'JAVA_OPTS' => '--add-opens=java.base/java.nio=ALL-UNNAMED',
18
+ 'PATH' => path
19
+ }
20
+ end
21
+
22
+ it 'prints chunk-scoped report only when internal errors are detected' do
23
+ root = File.expand_path('..', __dir__)
24
+ workdir = Dir.mktmpdir('gknit_internal_report_', root)
25
+
26
+ begin
27
+ rmd_path = File.join(workdir, 'internal_error.Rmd')
28
+ File.write(rmd_path, <<~RMD)
29
+ ---
30
+ title: "internal report"
31
+ output:
32
+ github_document: default
33
+ ---
34
+
35
+ ```{ruby bad_dev, dev='tiff'}
36
+ puts "x"
37
+ ```
38
+ RMD
39
+
40
+ rel_rmd = File.basename(workdir) + '/' + File.basename(rmd_path)
41
+ _out, err, st = Open3.capture3(
42
+ self.class.gknit_env,
43
+ 'bin/gknit', '--output_format', 'github_document', rel_rmd,
44
+ chdir: root
45
+ )
46
+
47
+ # Chunk-level errors are rendered inline; gknit process should still succeed.
48
+ expect(st.success?).to be(true)
49
+ expect(err).to include('gknit internal errors detected:')
50
+ expect(err).to include('chunk=bad_dev')
51
+ expect(err).to include('Unsupported graphics device')
52
+ ensure
53
+ FileUtils.rm_rf(workdir) if workdir && File.directory?(workdir)
54
+ end
55
+ end
56
+ end
57
+
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'open3'
5
+ require 'tmpdir'
6
+
7
+ describe 'gknit vector map output' do
8
+ def self.gknit_env
9
+ home = Dir.home
10
+ extra = [
11
+ File.join(home, 'bin'),
12
+ File.join(home, '.TinyTeX', 'bin')
13
+ ].select { |dir| File.directory?(dir) }
14
+ path = ENV.fetch('PATH', '')
15
+ path = ([*extra, path].join(File::PATH_SEPARATOR)) unless extra.empty?
16
+ {
17
+ 'JAVA_OPTS' => '--add-opens=java.base/java.nio=ALL-UNNAMED',
18
+ 'PATH' => path
19
+ }
20
+ end
21
+
22
+ it 'renders vec.map in ruby chunks without missing bridge methods' do
23
+ root = File.expand_path('..', __dir__)
24
+ workdir = Dir.mktmpdir('gknit_vec_map_', root)
25
+
26
+ begin
27
+ rmd_path = File.join(workdir, 'vector_map.Rmd')
28
+ File.write(rmd_path, <<~RMD)
29
+ ---
30
+ title: "gknit vector map"
31
+ output:
32
+ github_document: default
33
+ ---
34
+
35
+ ```{ruby, echo=FALSE}
36
+ vec = R.c(1, 2, 3, 4)
37
+ puts vec.map { |x| x + 2 }
38
+ ```
39
+ RMD
40
+
41
+ rel_rmd = File.basename(workdir) + '/' + File.basename(rmd_path)
42
+ out, err, st = Open3.capture3(
43
+ self.class.gknit_env,
44
+ 'bin/gknit', '--output_format', 'github_document', rel_rmd,
45
+ chdir: root
46
+ )
47
+ expect(st.success?).to be(true), "gknit failed\nstdout:\n#{out}\nstderr:\n#{err}"
48
+
49
+ md_path = rmd_path.sub(/\.Rmd\z/, '.md')
50
+ expect(File.exist?(md_path)).to be(true), "missing markdown output: #{md_path}"
51
+ md = File.read(md_path)
52
+
53
+ expect(md).to include('\\[1\\] 3 4 5 6')
54
+ expect(md).not_to include("undefined method 'push_double_vector'")
55
+ ensure
56
+ FileUtils.rm_rf(workdir) if workdir && File.directory?(workdir)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ describe 'GlobalEnv mutable write guardrail' do
6
+ it 'does not introduce unapproved .GlobalEnv$... <- writes in active bridge path' do
7
+ root = Pathname.new(__dir__).join('..').expand_path
8
+
9
+ scoped_files = Dir[root.join('lib/**/*.rb').to_s]
10
+
11
+ allow_by_file = {
12
+ 'lib/R_interface/rdevice.rb' => [
13
+ /\.GlobalEnv\$evaluate_plot_snapshot <- function\(\)/,
14
+ /\.GlobalEnv\$galaaz_save_plot <- function\(path, dev_type, width, height, dpi\)/
15
+ ],
16
+ 'lib/gknit/knitr_engine.rb' => [
17
+ /\.GlobalEnv\$knitr_dev2ext <- function\(x\)/,
18
+ /\.GlobalEnv\$g_simpleMessage <- function\(message\)/,
19
+ /\.GlobalEnv\$g_simpleWarning <- function\(message\)/,
20
+ /\.GlobalEnv\$evaluate_plot_snapshot <- function\(\)/,
21
+ /\.GlobalEnv\$save_recorded_plot <- function\(path, plot, width, height, dev, res, units\)/,
22
+ /\.GlobalEnv\$knitr_wrap <- function\(x, options\)/,
23
+ /\.GlobalEnv\$showtext <- function\(\)/
24
+ ],
25
+ 'lib/R_interface/rsupport.rb' => [
26
+ /assignment = "\.GlobalEnv\$\#\{var_name\} <- \{ \#\{final_r_code\}\\n \}"/,
27
+ /R\.bridge\.eval_r\("\.GlobalEnv\$\#\{var\} <- \#\{rhs\}"\)/
28
+ ],
29
+ 'lib/R_interface/robject.rb' => [
30
+ /assignment = "\.GlobalEnv\$\#\{var\} <- \#\{r_code\}"/
31
+ ],
32
+ 'lib/R_interface/rvector.rb' => [
33
+ /assignment = "\.GlobalEnv\$\#\{var_name\} <- \#\{@r_interop\}\[\[\#\{idx \+ 1\}\]\]"/
34
+ ]
35
+ }
36
+
37
+ violations = []
38
+
39
+ scoped_files.each do |file|
40
+ rel = Pathname.new(file).relative_path_from(root).to_s
41
+ lines = File.readlines(file, chomp: true)
42
+ lines.each_with_index do |line, idx|
43
+ next unless line.match?(/\.GlobalEnv\$.*<-/)
44
+
45
+ allowed = allow_by_file.fetch(rel, []).any? { |rx| line.match?(rx) }
46
+ violations << "#{rel}:#{idx + 1}: #{line.strip}" unless allowed
47
+ end
48
+ end
49
+
50
+ expect(violations).to eq([])
51
+ end
52
+ end