galaaz 0.5.0 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/LICENSE +0 -0
- data/README.md +1360 -636
- data/Rakefile +61 -41
- data/bin/galaaz-bootstrap +137 -0
- data/bin/galaaz-jruby +14 -0
- data/bin/galaaz_jruby_env.inc.sh +6 -0
- data/bin/gbookdown +64 -0
- data/bin/gknit +84 -13
- data/bin/gknit-draft.rb +0 -0
- data/bin/gstudio +5 -3
- data/bin/gstudio_irb.rb +0 -0
- data/bin/gstudio_pry.rb +0 -0
- data/bin/install-tinytex +6 -0
- data/bin/run_all_rspec +43 -0
- data/bin/run_example +14 -0
- data/bin/run_old_rspec +19 -0
- data/bin/run_rspec +23 -0
- data/bin/run_rspec_subset +38 -0
- data/bin/run_slow_rspec +19 -0
- data/blogs/R-on-Rails-Planning-Document.md +940 -0
- data/blogs/README.md +100 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +38 -66
- data/blogs/galaaz_ggplot/galaaz_ggplot.log +754 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot.md +115 -155
- data/blogs/galaaz_ggplot/galaaz_ggplot.tex +607 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/midwest_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/scatter_plot_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/midwest_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/scatter_plot_rb.png +0 -0
- data/blogs/galaaz_ggplot/midwest.Rmd +3 -3
- data/blogs/galaaz_ggplot/midwest_external_png +0 -0
- data/blogs/gknit/gknit.Rmd +47 -52
- data/blogs/gknit/gknit.md +1430 -0
- data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
- data/blogs/gknit/gknit_files/figure-html/diverging_bar.png +0 -0
- data/blogs/gknit/lst.rds +0 -0
- data/blogs/gknit/model.rb +1 -1
- data/blogs/gknit/stats.bib +0 -0
- data/blogs/manual/include_model_local_repro.Rmd +14 -0
- data/blogs/manual/include_model_local_repro.md +75 -0
- data/blogs/manual/lst.rds +0 -0
- data/blogs/manual/manual.Rmd +852 -239
- data/blogs/manual/manual.log +1786 -0
- data/blogs/manual/manual.md +1360 -636
- data/blogs/manual/manual.tex +1883 -1161
- data/blogs/manual/manual_files/figure-html/bubble-1.png +0 -0
- data/blogs/manual/manual_files/figure-html/diverging_bar.png +0 -0
- data/blogs/manual/manual_files/figure-latex/bubble-1.png +0 -0
- data/blogs/manual/model.rb +1 -1
- data/blogs/nse_dplyr/nse_dplyr.Rmd +84 -111
- data/blogs/nse_dplyr/nse_dplyr.log +928 -0
- data/blogs/nse_dplyr/nse_dplyr.md +198 -229
- data/blogs/oh_my/not_so.rb +0 -0
- data/blogs/oh_my/oh_my.Rmd +1234 -25
- data/blogs/oh_my/oh_my.log +804 -0
- data/blogs/oh_my/oh_my.md +1663 -86
- data/blogs/oh_my/oh_my.tex +821 -0
- data/blogs/oh_my/old.Rmd +15 -14
- data/blogs/ruby_plot/ruby_plot.Rmd +58 -82
- data/blogs/ruby_plot/ruby_plot.log +885 -0
- data/blogs/ruby_plot/ruby_plot.md +71 -102
- data/blogs/ruby_plot/ruby_plot.tex +940 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_decorations.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/dose_len.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_delivery.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_dose.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color2.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_decorations.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_points.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_box_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_violin_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/violin_with_jitter.png +0 -0
- data/blogs/test/test.Rmd +14 -0
- data/examples/50Plots_MasterList/Images/midwest-scatterplot.PNG +0 -0
- data/examples/50Plots_MasterList/ScatterPlot.rb +0 -0
- data/examples/50Plots_MasterList/scatter_plot.rb +0 -0
- data/examples/Bibliography/master.bib +0 -0
- data/examples/Bibliography/stats.bib +0 -0
- data/examples/R/calc.R +0 -0
- data/examples/R/java_interop.R +0 -0
- data/examples/bioconductor_deseq2_airway/Documentation/DESeq2-airway-walkthrough.md +56 -0
- data/examples/bioconductor_deseq2_airway/bench_galaaz_three_same_process.rb +53 -0
- data/examples/bioconductor_deseq2_airway/bench_r_three_same_process.R +34 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb +33 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz_optimized.rb +34 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_minimal.R +30 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_pipeline_for_bench.R +36 -0
- data/examples/islr/all.rb +13 -0
- data/examples/islr/ch2.spec.rb +37 -7
- data/examples/islr/ch3.spec.rb +11 -2
- data/examples/islr/ch3_boston.rb +27 -0
- data/examples/islr/ch3_multiple_regression.rb +0 -0
- data/examples/islr/ch6.spec.rb +24 -1
- data/examples/islr/x_y_rnorm.jpg +0 -0
- data/examples/latex_templates/Test-acm_article/acm_proc_article-sp.cls +0 -0
- data/examples/latex_templates/Test-acm_article/sigproc.bib +0 -0
- data/examples/latex_templates/Test-acs_article/acs-Test-acs_article.bib +0 -0
- data/examples/latex_templates/Test-acs_article/acs-my_output.bib +0 -0
- data/examples/latex_templates/Test-aea_article/BibFile.bib +0 -0
- data/examples/latex_templates/Test-aea_article/Test-aea_article.Rmd +0 -0
- data/examples/latex_templates/Test-aea_article/references.bib +0 -0
- data/examples/latex_templates/Test-amq_article/Test-amq_article.Rmd +0 -0
- data/examples/latex_templates/Test-amq_article/Test-amq_article.pdfsync +0 -0
- data/examples/latex_templates/Test-ieee_article/IEEEtran.bst +0 -0
- data/examples/latex_templates/Test-ieee_article/mybibfile.bib +0 -0
- data/examples/latex_templates/Test-rjournal_article/RJournal.sty +0 -0
- data/examples/latex_templates/Test-rjournal_article/RJreferences.bib +0 -0
- data/examples/latex_templates/Test-rjournal_article/Test-rjournal_article.Rmd +0 -0
- data/examples/misc/baseball.csv +0 -0
- data/examples/misc/ggplot.rb +3 -2
- data/examples/misc/moneyball.rb +0 -0
- data/examples/misc/subsetting.rb +0 -0
- data/examples/multithread_shards_to_r/shards_to_r.rb +67 -0
- data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-syllabus-example/attend-grade-relationships.csv +0 -0
- data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.Rmd +0 -0
- data/examples/rmarkdown/svm-xaringan-example/svm-xaringan-example.Rmd +0 -0
- data/examples/sthda_ggplot/README.md +0 -0
- data/examples/sthda_ggplot/RUN.md +41 -0
- data/examples/sthda_ggplot/all.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/density_gg.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_area.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_density.rb +2 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_dotplot.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_freqpoly.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_histogram.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/histogram_density.rb +0 -0
- data/examples/sthda_ggplot/one_variable_continuous/stat.rb +0 -0
- data/examples/sthda_ggplot/one_variable_discrete/bar.rb +0 -0
- data/examples/sthda_ggplot/qplots/box_violin_dot.rb +0 -0
- data/examples/sthda_ggplot/qplots/scatter_plots.rb +0 -0
- data/examples/sthda_ggplot/scatter_gg.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_bin2d.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_density2d.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_hex.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/geom_point.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/geom_smooth.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/misc.rb +0 -0
- data/examples/sthda_ggplot/two_variables_cont_function/geom_area.rb +4 -3
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_bar.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_boxplot.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_dotplot.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_jitter.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_line.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_violin.rb +0 -0
- data/examples/sthda_ggplot/two_variables_disc_disc/geom_jitter.rb +0 -0
- data/examples/sthda_ggplot/two_variables_error/geom_crossbar.rb +0 -0
- data/ext/new_bridge/Makefile +46 -0
- data/ext/new_bridge/galaaz_gatekeeper_phase0.cpp +12 -0
- data/ext/new_bridge/galaaz_gatekeeper_phase1.cpp +1639 -0
- data/lib/R_interface/galaaz_device.R +20 -0
- data/lib/R_interface/include_engine.R +109 -0
- data/lib/R_interface/new_bridge_adapter.rb +824 -0
- data/lib/R_interface/r.rb +177 -25
- data/lib/R_interface/r_arrow.rb +113 -0
- data/lib/R_interface/r_libs.R +3 -3
- data/lib/R_interface/r_methods.rb +13 -126
- data/lib/R_interface/r_module_s.rb +0 -0
- data/lib/R_interface/rbinary_operators.rb +20 -2
- data/lib/R_interface/rclosure.rb +5 -1
- data/lib/R_interface/rdata_frame.rb +34 -70
- data/lib/R_interface/rdevice.rb +125 -0
- data/lib/R_interface/rdevices.R +0 -0
- data/lib/R_interface/renvironment.rb +10 -4
- data/lib/R_interface/rexpression.rb +5 -1
- data/lib/R_interface/rindexed_object.rb +41 -13
- data/lib/R_interface/rlanguage.rb +20 -62
- data/lib/R_interface/rlist.rb +115 -25
- data/lib/R_interface/rlogical_operators.rb +0 -0
- data/lib/R_interface/rmatrix.rb +2 -11
- data/lib/R_interface/rmd_indexed_object.rb +5 -1
- data/lib/R_interface/robject.rb +348 -290
- data/lib/R_interface/rpkg.rb +0 -0
- data/lib/R_interface/rsupport.rb +609 -328
- data/lib/R_interface/rsupport_scope.rb +2 -1
- data/lib/R_interface/rsymbol.rb +50 -0
- data/lib/R_interface/ruby_callback.rb +2 -3
- data/lib/R_interface/ruby_extensions.rb +225 -175
- data/lib/R_interface/runary_operators.rb +0 -0
- data/lib/R_interface/rvector.rb +147 -31
- data/lib/galaaz.rb +0 -0
- data/lib/galaaz_jruby.rb +22 -0
- data/lib/gknit/diagnostics.rb +50 -0
- data/lib/gknit/draft.rb +23 -17
- data/lib/gknit/include_engine.rb +15 -7
- data/lib/gknit/knitr_engine.rb +223 -74
- data/lib/gknit/rb_engine.rb +3 -3
- data/lib/gknit/ruby_engine.rb +0 -0
- data/lib/gknit.rb +1 -0
- data/lib/new_bridge/bootstrap/windows_bootstrap.rb +285 -0
- data/lib/new_bridge/envelope.rb +51 -0
- data/lib/new_bridge/eval_result.rb +26 -0
- data/lib/new_bridge/framing.rb +39 -0
- data/lib/new_bridge/instance_pool_client.rb +38 -0
- data/lib/new_bridge/r_instance_manager.rb +404 -0
- data/lib/new_bridge/session_client.rb +530 -0
- data/lib/new_bridge/tcp_framed.rb +44 -0
- data/lib/new_bridge.rb +9 -0
- data/lib/util/exec_ruby.rb +95 -20
- data/lib/util/inline_file.rb +35 -30
- data/new_bridge_specs/benchmark_phase5_5_unboxing_spec.rb +96 -0
- data/new_bridge_specs/eval_r_async_spec.rb +113 -0
- data/new_bridge_specs/integration_phase5_1_concurrent_spec.rb +50 -0
- data/new_bridge_specs/integration_phase5_1_eval_spec.rb +16 -0
- data/new_bridge_specs/integration_phase5_1_r_api_spec.rb +25 -0
- data/new_bridge_specs/integration_phase5_1_smoke_spec.rb +31 -0
- data/new_bridge_specs/integration_phase5_2_dataframe_unboxing_spec.rb +19 -0
- data/new_bridge_specs/integration_phase5_2_handle_eval_unboxing_spec.rb +25 -0
- data/new_bridge_specs/integration_phase5_3_callback_args_spec.rb +28 -0
- data/new_bridge_specs/integration_phase5_3_callback_error_spec.rb +22 -0
- data/new_bridge_specs/integration_phase5_3_callback_timeout_spec.rb +28 -0
- data/new_bridge_specs/integration_phase5_3_callbacks_smoke_spec.rb +22 -0
- data/new_bridge_specs/integration_phase5_3_edge_cases_spec.rb +52 -0
- data/new_bridge_specs/integration_phase5_3_nested_spec.rb +30 -0
- data/new_bridge_specs/integration_phase5_4_concurrent_sessions_spec.rb +53 -0
- data/new_bridge_specs/integration_phase5_4_nested_session_callbacks_spec.rb +49 -0
- data/new_bridge_specs/integration_phase5_4_session_routing_spec.rb +38 -0
- data/new_bridge_specs/integration_phase5_5_stress_concurrency_spec.rb +52 -0
- data/new_bridge_specs/integration_phase5_5_unbox_walk_spec.rb +46 -0
- data/new_bridge_specs/phase0_protocol_spec.rb +96 -0
- data/new_bridge_specs/phase1_req_ret_spec.rb +66 -0
- data/new_bridge_specs/phase2_multi_instance_spec.rb +67 -0
- data/new_bridge_specs/phase3_callbacks_spec.rb +71 -0
- data/new_bridge_specs/phase4_2_hardening_spec.rb +252 -0
- data/new_bridge_specs/phase4_3_r_instance_manager_spec.rb +85 -0
- data/new_bridge_specs/phase4_nested_callbacks_spec.rb +123 -0
- data/r_requires/ggplot.rb +0 -0
- data/r_requires/knitr.rb +0 -0
- data/specs/all.rb +15 -11
- data/specs/arrow_from_ruby_batches_spec.rb +50 -0
- data/specs/arrow_semantics_spec.rb +64 -0
- data/specs/bridge_concurrent_spec.rb +46 -0
- data/specs/bridge_nested_spec.rb +25 -0
- data/specs/dataframe_semantics_spec.rb +122 -0
- data/specs/dataframe_single_index_logical_filter_spec.rb +21 -0
- data/specs/dispatch_probe_cache_spec.rb +38 -0
- data/specs/dispatch_probe_error_class_fallback_spec.rb +20 -0
- data/specs/dispatch_probe_fallback_spec.rb +18 -0
- data/specs/environment_semantics_spec.rb +89 -0
- data/specs/field_access_spec.rb +31 -0
- data/specs/figures/bg.jpeg +0 -0
- data/specs/figures/bg.png +0 -0
- data/specs/figures/bg.svg +168 -57
- data/specs/figures/dose_len.png +0 -0
- data/specs/figures/no_args.jpeg +0 -0
- data/specs/figures/no_args.png +0 -0
- data/specs/figures/no_args.svg +168 -57
- data/specs/figures/width_height.jpeg +0 -0
- data/specs/figures/width_height.png +0 -0
- data/specs/figures/width_height_units1.jpeg +0 -0
- data/specs/figures/width_height_units1.png +0 -0
- data/specs/figures/width_height_units2.jpeg +0 -0
- data/specs/figures/width_height_units2.png +0 -0
- data/specs/formula_semantics_spec.rb +81 -0
- data/specs/galaaz_util_exec_ruby_spec.rb +85 -0
- data/specs/galaaz_util_inline_file_spec.rb +54 -0
- data/specs/gknit_cli_option_permutation_spec.rb +24 -0
- data/specs/gknit_include_engine_spec.rb +72 -0
- data/specs/gknit_install_timeout_report_spec.rb +69 -0
- data/specs/gknit_internal_error_report_spec.rb +57 -0
- data/specs/gknit_vector_map_output_spec.rb +59 -0
- data/specs/globalenv_guardrail_spec.rb +52 -0
- data/specs/language_expression_semantics_spec.rb +145 -0
- data/specs/list_semantics_spec.rb +111 -0
- data/specs/new_bridge_bulk_dataframe_transfer_spec.rb +44 -0
- data/specs/new_bridge_bulk_vector_transfer_spec.rb +73 -0
- data/specs/new_bridge_callback_timeout_spec.rb +69 -0
- data/specs/new_bridge_eval_r_fallback_spec.rb +55 -0
- data/specs/nil_null_spec.rb +42 -0
- data/specs/object_build_phase2_spec.rb +53 -0
- data/specs/phase1_callback_bridge_spec.rb +84 -0
- data/specs/phase2_gknit_generic_rendering_guardrail_spec.rb +46 -0
- data/specs/phase2_gknit_no_raw_code_leakage_spec.rb +43 -0
- data/specs/phase3_gknit_generic_graphics_capture_spec.rb +71 -0
- data/specs/plot_device_semantics_spec.rb +28 -0
- data/specs/plot_snapshot_semantics_spec.rb +58 -0
- data/specs/protocol_result_spec.rb +236 -0
- data/specs/r_batch_fail_fast_spec.rb +47 -0
- data/specs/r_bridge_bootstrap_spec.rb +11 -0
- data/specs/r_devices.spec.rb +1 -1
- data/specs/r_eval.spec.rb +16 -18
- data/specs/r_function.spec.rb +1 -1
- data/specs/r_instance_manager_spec.rb +285 -0
- data/specs/r_list_apply.spec.rb +15 -15
- data/specs/r_matrix.spec.rb +0 -0
- data/specs/r_nse.spec.rb +5 -5
- data/specs/r_object_send_dispatch_spec.rb +13 -0
- data/specs/r_vector_comparator_spec.rb +8 -0
- data/specs/r_vector_creation.spec.rb +0 -0
- data/specs/r_vector_functions.spec.rb +0 -0
- data/specs/r_vector_object.spec.rb +0 -0
- data/specs/r_vector_operators.spec.rb +0 -0
- data/specs/r_vector_structured_scalar_reads_spec.rb +35 -0
- data/specs/r_vector_subsetting.spec.rb +0 -0
- data/specs/range_helper_spec.rb +21 -0
- data/specs/rsupport_scope_spec.rb +28 -0
- data/specs/rsupport_var_name_thread_safety_spec.rb +24 -0
- data/specs/scalar_character_spec.rb +44 -0
- data/specs/scoped_symbol_dsl_refinement_spec.rb +40 -0
- data/specs/session_env_bridge_spec.rb +25 -0
- data/specs/simplecov_bootstrap_spec.rb +10 -0
- data/specs/spec_helper.rb +10 -0
- data/specs/tmp.rb +0 -0
- data/specs/unboxing_recursion_regression_spec.rb +30 -0
- data/specs/unboxing_spec.rb +49 -0
- data/specs/verify_callbacks.rb +42 -0
- data/sty/galaaz.sty +0 -0
- data/version.rb +1 -1
- metadata +194 -64
- data/blogs/galaaz_ggplot/galaaz_ggplot.html +0 -520
- data/blogs/galaaz_ggplot/galaaz_ggplot.pdf +0 -0
- data/blogs/galaaz_ggplot/midwest.html +0 -188
- data/blogs/gknit/gknit.html +0 -2266
- data/blogs/gknit/gknit.pdf +0 -0
- data/blogs/manual/manual.html +0 -4638
- data/blogs/manual/manual.pdf +0 -0
- data/blogs/manual/manual_files/figure-latex/diverging_bar.pdf +0 -0
- data/blogs/nse_dplyr/nse_dplyr.html +0 -878
- data/blogs/nse_dplyr/nse_dplyr.pdf +0 -0
- data/blogs/oh_my/oh_my.html +0 -568
- data/blogs/ruby_plot/ruby_plot.html +0 -544
- data/blogs/ruby_plot/ruby_plot.pdf +0 -0
- data/examples/latex_templates/Test-acs_article/Test-acs_article.pdf +0 -0
- data/examples/latex_templates/Test-aea_article/Test-aea_article.pdf +0 -0
- data/examples/latex_templates/Test-amq_article/Test-amq_article.pdf +0 -0
- data/examples/latex_templates/Test-amq_article/pics/Figure2.pdf +0 -0
- data/examples/latex_templates/Test-asa_article/Test-asa_article.pdf +0 -0
- data/examples/latex_templates/Test-ieee_article/Test-ieee_article.pdf +0 -0
- data/examples/latex_templates/Test-rjournal_article/RJwrapper.pdf +0 -0
- data/examples/latex_templates/Test-springer_article/Test-springer_article.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.pdf +0 -0
- data/specs/r_dataframe.spec.rb +0 -379
- data/specs/r_environment.spec.rb +0 -140
- data/specs/r_formula.spec.rb +0 -232
- data/specs/r_language.spec.rb +0 -112
- data/specs/r_list.spec.rb +0 -293
- data/specs/r_plots.spec.rb +0 -72
- data/specs/ruby_expression.spec.rb +0 -316
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'galaaz'
|
|
4
|
+
|
|
5
|
+
describe 'Language and expression semantics' do
|
|
6
|
+
context 'symbol conversion and expression building' do
|
|
7
|
+
before(:each) do
|
|
8
|
+
R.len = 10
|
|
9
|
+
R.sd = 20
|
|
10
|
+
R.x = 5
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "converts Ruby Symbol to R symbol with unary '+'" do
|
|
14
|
+
sym = +R[:len]
|
|
15
|
+
expect(sym).to be_a(R::RSymbol)
|
|
16
|
+
expect(sym.to_s).to eq('len')
|
|
17
|
+
expect(sym.eval).to eq 10
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'builds language expressions from symbol arithmetic' do
|
|
21
|
+
expr = R[:len] + R[:sd] + 5
|
|
22
|
+
expect(expr).to be_a(R::Language)
|
|
23
|
+
expect(expr.to_s).to eq('len + sd + 5L')
|
|
24
|
+
expect(expr.eval).to eq R.c(35)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'supports comparison operators in expressions' do
|
|
28
|
+
df = R.data__frame(a: (1..5), b: (5..1))
|
|
29
|
+
e = R[:a] > R[:b]
|
|
30
|
+
expect(e.to_s).to eq('a > b')
|
|
31
|
+
expect(e.eval(df)).to eq R.c(false, false, false, true, true)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'supports custom infix operators with scoped symbols' do
|
|
35
|
+
e = R[:month]._ :in, R.c(11, 12)
|
|
36
|
+
expect(e.to_s).to include('month %in%')
|
|
37
|
+
df = R.data__frame(month: R.c(10, 11, 12, 1))
|
|
38
|
+
expect(e.eval(df)).to eq R.c(false, true, true, false)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'supports quoted function construction through E helper' do
|
|
42
|
+
exp = E.sin(:len)
|
|
43
|
+
expect(exp).to be_a(R::Language)
|
|
44
|
+
expect(exp.to_s).to eq('sin(len)')
|
|
45
|
+
expect(exp.eval).to eq R.c(Math.sin(10))
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context 'evaluation with context objects' do
|
|
50
|
+
it 'evaluates composite arithmetic expression in list context' do
|
|
51
|
+
ctx = R.list(a: 10, b: 20, c: 30)
|
|
52
|
+
val = R.eval(R[:a] + R[:b] * R[:c], ctx)
|
|
53
|
+
expect(val).to eq 610
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'evaluates expression against global binding when no context is provided' do
|
|
57
|
+
R.x = 5
|
|
58
|
+
expect(R.eval(R[:x] + 10)).to eq 15
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'evaluates expression in list context via R.eval(expr, ctx)' do
|
|
62
|
+
ctx = R.list(x: 20)
|
|
63
|
+
val = R.eval(R[:x] + 10, ctx)
|
|
64
|
+
expect(val).to be_a(R::Vector)
|
|
65
|
+
expect(val >> 0).to eq 30
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'uses expression predicates in subset()' do
|
|
69
|
+
df = R.data__frame(a: (1..5), b: (5..1), c: R.c(5, 3, 1, 4, 1))
|
|
70
|
+
sub = R.subset(df, R[:a] >= 4)
|
|
71
|
+
expect(sub).to be_a(R::DataFrame)
|
|
72
|
+
expect(sub.nrow >> 0).to eq 2
|
|
73
|
+
expect(sub[1, 1]).to eq 4
|
|
74
|
+
expect(sub[2, 2]).to eq 1
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'supports scoped arithmetic expressions inside mutate assignments' do
|
|
78
|
+
ok = R::Support.eval("requireNamespace('dplyr', quietly=TRUE)")
|
|
79
|
+
skip 'dplyr is not available' unless ok == true
|
|
80
|
+
R.library('dplyr')
|
|
81
|
+
|
|
82
|
+
flights_sm = R.data__frame(
|
|
83
|
+
dep_delay: R.c(10, 20),
|
|
84
|
+
arr_delay: R.c(5, 7),
|
|
85
|
+
distance: R.c(300, 600),
|
|
86
|
+
air_time: R.c(60, 120)
|
|
87
|
+
).mutate(
|
|
88
|
+
gain: R[:dep_delay] - R[:arr_delay],
|
|
89
|
+
speed: R[:distance] / R[:air_time] * 60
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
expect(flights_sm[['gain']][1]).to eq 5
|
|
93
|
+
expect(flights_sm[['gain']][2]).to eq 13
|
|
94
|
+
expect(flights_sm[['speed']][1]).to eq 300
|
|
95
|
+
expect(flights_sm[['speed']][2]).to eq 300
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'supports scoped chained list call for column selection expressions' do
|
|
99
|
+
expr = R[:arr_delay].list
|
|
100
|
+
expect(expr).to be_a(R::Language)
|
|
101
|
+
expect(expr.to_s).to eq('list(arr_delay)')
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
context 'reintroduced rlang helper APIs' do
|
|
106
|
+
before(:all) do
|
|
107
|
+
ok = R::Support.eval("requireNamespace('rlang', quietly=TRUE)")
|
|
108
|
+
skip 'R package rlang is not available' unless ok == true
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'supports R.expr for symbol construction' do
|
|
112
|
+
R.len = 10
|
|
113
|
+
exp = R.expr(:len)
|
|
114
|
+
expect(exp).to be_a(R::RSymbol)
|
|
115
|
+
expect(exp.eval).to eq 10
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'supports R.expr for boolean literals' do
|
|
119
|
+
expect(R.expr(true)).to eq R.c(true)
|
|
120
|
+
expect(R.expr(false)).to eq R.c(false)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it 'supports R.call2 for call construction' do
|
|
124
|
+
e = R.call2('mean', x: +R[:x], na__rm: true)
|
|
125
|
+
expect(e).to be_a(R::Language)
|
|
126
|
+
expect(e.to_s).to eq('mean(x = x, na.rm = TRUE)')
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it 'supports R.call2 for assignment calls' do
|
|
130
|
+
e = R.call2('<-', R.expr(:x), 10)
|
|
131
|
+
e.eval
|
|
132
|
+
expect(~R[:x]).to eq 10
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it 'supports R.exec for dynamic function execution' do
|
|
136
|
+
val = R.exec('mean', x: (1..10), na__rm: true, trim: 0.1)
|
|
137
|
+
expect(val).to eq 5.5
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it 'supports R.exec with splatted argument hashes' do
|
|
141
|
+
args = [x: (1..10), na__rm: true, trim: 0.1]
|
|
142
|
+
expect(R.exec('mean', *args)).to eq 5.5
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'galaaz'
|
|
4
|
+
|
|
5
|
+
describe R::List do
|
|
6
|
+
context 'creation and unboxing' do
|
|
7
|
+
it 'creates empty and populated lists' do
|
|
8
|
+
empty = R.list
|
|
9
|
+
expect(empty.length).to eq 0
|
|
10
|
+
expect(empty).to be_a(R::List)
|
|
11
|
+
|
|
12
|
+
l = R.list(1, a: 2, b: 3, c: R.list(4, 5, 6))
|
|
13
|
+
expect(l.length).to eq 4
|
|
14
|
+
expect(l >> 0).to eq 1
|
|
15
|
+
expect(l >> 3).to eq [4, 5, 6]
|
|
16
|
+
expect(l['k'] >> 0).to eq nil
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context "subsetting with '[' and '[['" do
|
|
21
|
+
before(:each) do
|
|
22
|
+
@l = R.list(a: 1, b: 2, all: 3, d: R.list(i: 4, j: 5, all: 6))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'returns a list when using []' do
|
|
26
|
+
expect(@l[1]).to eq R.list(a: 1)
|
|
27
|
+
expect(@l[-4] == R.list(a: 1, b: 2, all: 3)).to eq true
|
|
28
|
+
expect(@l[R.c(4, 1)] == R.list(d: R.list(i: 4, j: 5, all: 6), a: 1)).to eq true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'raises bridge process error when [] receives wrong index dimension' do
|
|
32
|
+
expect { @l[4, 1] }.to raise_error(NewBridge::SessionClient::RProcessError)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'returns elements when using [[]]' do
|
|
36
|
+
raw = R.list(1, 2, 3, R.list(4, 5, 6))
|
|
37
|
+
expect(raw[[1]]).to eq 1
|
|
38
|
+
expect(raw[[4]].identical(R.list(4, 5, 6))).to eq true
|
|
39
|
+
expect(raw[[4]][[1]]).to eq 4
|
|
40
|
+
expect(raw[[R.c(4, 1)]]).to eq 4
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context 'named access and assignment' do
|
|
45
|
+
before(:each) do
|
|
46
|
+
@l = R.list(a: 1, b: 2, c: 3, d: R.list(i: 4, j: 5, k: 6))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'supports dot access for named elements' do
|
|
50
|
+
expect(@l.a).to eq 1
|
|
51
|
+
expect(@l.d.identical(R.list(i: 4, j: 5, k: 6))).to eq true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'supports setting and removing named elements' do
|
|
55
|
+
@l[['a']] = 10
|
|
56
|
+
@l.b = 20
|
|
57
|
+
@l.married = true
|
|
58
|
+
expect(@l[['a']]).to eq 10
|
|
59
|
+
expect(@l.b).to eq 20
|
|
60
|
+
expect(@l.married).to eq true
|
|
61
|
+
|
|
62
|
+
@l.d = nil
|
|
63
|
+
expect(@l.length).to eq 4
|
|
64
|
+
expect(@l[['d']]).to eq nil
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context 'iteration and richer assignment paths' do
|
|
69
|
+
it 'iterates list elements with each and each_with_index' do
|
|
70
|
+
l = R.list(1, 2, 3, R.list(4, 5, 6))
|
|
71
|
+
|
|
72
|
+
got_each = []
|
|
73
|
+
l.each do |el|
|
|
74
|
+
got_each << (el.is_a?(R::Object) ? el.to_ruby : el)
|
|
75
|
+
end
|
|
76
|
+
expect(got_each).to eq([1, 2, 3, [4, 5, 6]])
|
|
77
|
+
|
|
78
|
+
got_each_idx = []
|
|
79
|
+
l.each_with_index do |el, idx|
|
|
80
|
+
val = el.is_a?(R::Object) ? el.to_ruby : el
|
|
81
|
+
got_each_idx << [idx, val]
|
|
82
|
+
end
|
|
83
|
+
expect(got_each_idx).to eq([[1, 1], [2, 2], [3, 3], [4, [4, 5, 6]]])
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'supports richer add/modify/remove assignment forms' do
|
|
87
|
+
l = R.list(a: 1, b: 2, c: 3, d: R.list(i: 4, j: 5, k: 6))
|
|
88
|
+
l[[1]] = 10
|
|
89
|
+
expect(l[[1]]).to eq 10
|
|
90
|
+
|
|
91
|
+
l[['a']] = 11
|
|
92
|
+
l.b = 22
|
|
93
|
+
l.married = true
|
|
94
|
+
l.number = 5.345
|
|
95
|
+
l.lst = R.list(100, 200)
|
|
96
|
+
l.vec = R.c(500, 600)
|
|
97
|
+
|
|
98
|
+
expect(l[['a']]).to eq 11
|
|
99
|
+
expect(l.b).to eq 22
|
|
100
|
+
expect(l.married).to eq true
|
|
101
|
+
expect(l.number).to eq 5.345
|
|
102
|
+
expect(l.lst).to eq R.list(100, 200)
|
|
103
|
+
expect(l.vec).to eq R.c(500, 600)
|
|
104
|
+
|
|
105
|
+
l.d = nil
|
|
106
|
+
expect(l[['d']]).to eq nil
|
|
107
|
+
l[['vec']] = nil
|
|
108
|
+
expect(l[['vec']]).to eq nil
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'galaaz'
|
|
4
|
+
|
|
5
|
+
describe 'NewBridge bulk data.frame pull (column-wise + pull_vector)' do
|
|
6
|
+
it 'unboxes data.frame to Ruby hash with correct columns' do
|
|
7
|
+
df = R.data__frame(x: R.c(1, 2, 3), y: R.c('a', 'b', 'c'))
|
|
8
|
+
ruby = df.to_ruby
|
|
9
|
+
expect(ruby).to be_a(Hash)
|
|
10
|
+
expect(ruby['x']).to eq([1, 2, 3])
|
|
11
|
+
expect(ruby['y']).to eq(%w[a b c])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'preserves NA in numeric and logical columns' do
|
|
15
|
+
h = R::Support.generate_var_name
|
|
16
|
+
R.bridge.eval_r("#{h} <- data.frame(a = c(1, NA_real_), b = c(TRUE, NA), stringsAsFactors = FALSE)")
|
|
17
|
+
raw = R.bridge.pull_dataframe(h)
|
|
18
|
+
expect(raw['a'][0]).to eq(1.0)
|
|
19
|
+
expect(raw['a'][1]).to be_nil
|
|
20
|
+
expect(raw['b'][0]).to eq(true)
|
|
21
|
+
expect(raw['b'][1]).to eq(R::NA)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'uses one bulk pull per atomic column (not per cell)' do
|
|
25
|
+
client = R.bridge.instance_variable_get(:@client)
|
|
26
|
+
bulk = 0
|
|
27
|
+
allow(client).to receive(:eval_r).and_wrap_original do |m, code, **kwargs|
|
|
28
|
+
bulk += 1 if code.to_s.start_with?('__G_PULL_VECTOR__')
|
|
29
|
+
m.call(code, **kwargs)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
df = R.data__frame(u: R.c(10, 20), v: R.c(1.5, 2.5), w: R.c(true, false))
|
|
33
|
+
df.to_ruby
|
|
34
|
+
expect(bulk).to eq(3)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'matches manual column bind for zero-row data.frame' do
|
|
38
|
+
h = R::Support.generate_var_name
|
|
39
|
+
R.bridge.eval_r("#{h} <- data.frame(x = numeric(0), y = character(0), stringsAsFactors = FALSE)")
|
|
40
|
+
raw = R.bridge.pull_dataframe(h)
|
|
41
|
+
expect(raw['x']).to eq([])
|
|
42
|
+
expect(raw['y']).to eq([])
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'galaaz'
|
|
4
|
+
|
|
5
|
+
describe 'NewBridge bulk vector pull (__G_PULL_VECTOR__)' do
|
|
6
|
+
it 'pulls full integer vector in one gatekeeper call' do
|
|
7
|
+
client = R.bridge.instance_variable_get(:@client)
|
|
8
|
+
bulk_cmds = []
|
|
9
|
+
allow(client).to receive(:eval_r).and_wrap_original do |m, code, **kwargs|
|
|
10
|
+
bulk_cmds << code.to_s if code.to_s.start_with?('__G_PULL_VECTOR__')
|
|
11
|
+
m.call(code, **kwargs)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
v = R.c(7, 8, 9)
|
|
15
|
+
arr = v >> nil
|
|
16
|
+
expect(arr).to eq([7, 8, 9])
|
|
17
|
+
expect(bulk_cmds.any? { |c| c =~ /\A__G_PULL_VECTOR__\|g2_v\d+\z/ }).to eq(true)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'pulls double vector with NA as nil' do
|
|
21
|
+
h = R::Support.generate_var_name
|
|
22
|
+
R.bridge.eval_r("#{h} <- c(1.0, NA_real_, 3.0)")
|
|
23
|
+
arr = R.bridge.pull_vector(h)
|
|
24
|
+
expect(arr[0]).to eq(1.0)
|
|
25
|
+
expect(arr[1]).to be_nil
|
|
26
|
+
expect(arr[2]).to eq(3.0)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'pulls logical vector with NA mapped to R::NA' do
|
|
30
|
+
v = R.c(true, false, R::NA)
|
|
31
|
+
arr = v >> nil
|
|
32
|
+
expect(arr[0]).to eq(true)
|
|
33
|
+
expect(arr[1]).to eq(false)
|
|
34
|
+
expect(arr[2]).to eq(R::NA)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'pulls character vector with NA as nil' do
|
|
38
|
+
v = R.c('x', 'y')
|
|
39
|
+
arr = v >> nil
|
|
40
|
+
expect(arr).to eq(%w[x y])
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'matches elementwise pull for medium-length numeric vector' do
|
|
44
|
+
n = 500
|
|
45
|
+
h = R::Support.generate_var_name
|
|
46
|
+
R.bridge.eval_r("#{h} <- 1:#{n}")
|
|
47
|
+
bridge = R.bridge
|
|
48
|
+
bulk = bridge.pull_vector(h)
|
|
49
|
+
elementwise = bridge.send(:pull_vector_elementwise, h)
|
|
50
|
+
expect(bulk.size).to eq(n)
|
|
51
|
+
expect(bulk).to eq(elementwise)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'pull_integer_vector slice matches elementwise' do
|
|
55
|
+
h = R::Support.generate_var_name
|
|
56
|
+
R.bridge.eval_r("#{h} <- 10:19")
|
|
57
|
+
bridge = R.bridge
|
|
58
|
+
slice = bridge.pull_integer_vector(h, 10, 2, 4)
|
|
59
|
+
expect(slice).to eq([12, 13, 14, 15])
|
|
60
|
+
slow = bridge.send(:pull_integer_vector_elementwise, h, 2, 4)
|
|
61
|
+
expect(slice).to eq(slow)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'pull_double_vector slice matches elementwise for doubles' do
|
|
65
|
+
h = R::Support.generate_var_name
|
|
66
|
+
R.bridge.eval_r("#{h} <- as.numeric(1:5) + 0.5")
|
|
67
|
+
bridge = R.bridge
|
|
68
|
+
slice = bridge.pull_double_vector(h, 5, 1, 3)
|
|
69
|
+
expect(slice.size).to eq(3)
|
|
70
|
+
slow = bridge.send(:pull_double_vector_elementwise, h, 1, 3)
|
|
71
|
+
expect(slice).to eq(slow)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'galaaz'
|
|
4
|
+
|
|
5
|
+
describe 'NewBridge callback timeout configuration' do
|
|
6
|
+
it 'embeds GALAAZ_CALLBACK_TIMEOUT_MS into callback stub wait time' do
|
|
7
|
+
old = ENV['GALAAZ_CALLBACK_TIMEOUT_MS']
|
|
8
|
+
ENV['GALAAZ_CALLBACK_TIMEOUT_MS'] = '123456'
|
|
9
|
+
|
|
10
|
+
begin
|
|
11
|
+
stub = R.bridge.register_callback_proc_stub(proc { |_x| nil })
|
|
12
|
+
expect(stub).to include('galaaz_callback_call_phase3')
|
|
13
|
+
expect(stub).to include('123456')
|
|
14
|
+
ensure
|
|
15
|
+
ENV['GALAAZ_CALLBACK_TIMEOUT_MS'] = old
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'uses GALAAZ_BRIDGE_TIMEOUT_SEC as default eval timeout' do
|
|
20
|
+
old = ENV['GALAAZ_BRIDGE_TIMEOUT_SEC']
|
|
21
|
+
ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'] = '321'
|
|
22
|
+
|
|
23
|
+
begin
|
|
24
|
+
client = R.bridge.instance_variable_get(:@client)
|
|
25
|
+
captured = nil
|
|
26
|
+
allow(client).to receive(:eval_r).and_wrap_original do |m, *args, **kwargs|
|
|
27
|
+
captured = kwargs[:timeout]
|
|
28
|
+
m.call(*args, **kwargs)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
R.bridge.eval_r('1+1')
|
|
32
|
+
expect(captured).to eq(321)
|
|
33
|
+
ensure
|
|
34
|
+
ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'] = old
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'uses GALAAZ_BRIDGE_TIMEOUT_SEC in session helper evals' do
|
|
39
|
+
old = ENV['GALAAZ_BRIDGE_TIMEOUT_SEC']
|
|
40
|
+
ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'] = '321'
|
|
41
|
+
|
|
42
|
+
begin
|
|
43
|
+
client = R.bridge.instance_variable_get(:@client)
|
|
44
|
+
captured = nil
|
|
45
|
+
allow(client).to receive(:eval_r).and_wrap_original do |m, *args, **kwargs|
|
|
46
|
+
captured = kwargs[:timeout] if args[0].to_s.include?('galaaz_assign_session')
|
|
47
|
+
m.call(*args, **kwargs)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
R.bridge.assign_session('spec_session', 'spec_key', '1L')
|
|
51
|
+
expect(captured).to eq(321)
|
|
52
|
+
ensure
|
|
53
|
+
ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'] = old
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'does not clear callback timeout env when no per-call override is provided' do
|
|
58
|
+
old = ENV['GALAAZ_CALLBACK_TIMEOUT_MS']
|
|
59
|
+
ENV['GALAAZ_CALLBACK_TIMEOUT_MS'] = '7200000'
|
|
60
|
+
|
|
61
|
+
begin
|
|
62
|
+
R.with_callback_timeout_ms(nil) { 1 + 1 }
|
|
63
|
+
expect(ENV['GALAAZ_CALLBACK_TIMEOUT_MS']).to eq('7200000')
|
|
64
|
+
ensure
|
|
65
|
+
ENV['GALAAZ_CALLBACK_TIMEOUT_MS'] = old
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'galaaz'
|
|
2
|
+
|
|
3
|
+
describe R::NewBridgeAdapter do
|
|
4
|
+
let(:bridge) { R.bridge }
|
|
5
|
+
let(:client) { bridge.instance_variable_get(:@client) }
|
|
6
|
+
|
|
7
|
+
it 'retries in side-effect mode for exact phase1 scalar limitation error' do
|
|
8
|
+
calls = []
|
|
9
|
+
err = NewBridge::SessionClient::RProcessError.new('phase1 requires length-1 scalar')
|
|
10
|
+
|
|
11
|
+
allow(client).to receive(:eval_r).and_wrap_original do |_m, code, **kwargs|
|
|
12
|
+
calls << [code, kwargs]
|
|
13
|
+
if calls.length == 1
|
|
14
|
+
raise err
|
|
15
|
+
else
|
|
16
|
+
{ 'kind' => 'integer', 'value' => 0 }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
result = bridge.eval_r('function(x) { x }')
|
|
21
|
+
|
|
22
|
+
expect(result).to eq('')
|
|
23
|
+
expect(calls.length).to eq(2)
|
|
24
|
+
expect(calls[1][0]).to eq('({ function(x) { x }; 0L })')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'retries in side-effect mode for exact unsupported type error' do
|
|
28
|
+
calls = []
|
|
29
|
+
err = NewBridge::SessionClient::RProcessError.new('unsupported type')
|
|
30
|
+
|
|
31
|
+
allow(client).to receive(:eval_r).and_wrap_original do |_m, code, **kwargs|
|
|
32
|
+
calls << [code, kwargs]
|
|
33
|
+
if calls.length == 1
|
|
34
|
+
raise err
|
|
35
|
+
else
|
|
36
|
+
{ 'kind' => 'integer', 'value' => 0 }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
result = bridge.eval_r('x <- c(1,2,3)')
|
|
41
|
+
|
|
42
|
+
expect(result).to eq('')
|
|
43
|
+
expect(calls.length).to eq(2)
|
|
44
|
+
expect(calls[1][0]).to eq('({ x <- c(1,2,3); 0L })')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'does not swallow unrelated RProcessError even with similar words' do
|
|
48
|
+
err = NewBridge::SessionClient::RProcessError.new('Error: unrelated unsupported type mismatch on user code')
|
|
49
|
+
allow(client).to receive(:eval_r).and_raise(err)
|
|
50
|
+
|
|
51
|
+
expect do
|
|
52
|
+
bridge.eval_r('stop("boom")')
|
|
53
|
+
end.to raise_error(NewBridge::SessionClient::RProcessError, /unrelated unsupported type mismatch/)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Specs for NilClass#is__null and #isTRUE (R NULL becomes Ruby nil; calling
|
|
3
|
+
# .is__null or .isTRUE on nil must not raise and must behave like R's is.null(NULL) / isTRUE(NULL)).
|
|
4
|
+
#
|
|
5
|
+
# Run with: bin/run_rspec specs/nil_null_spec.rb
|
|
6
|
+
# (plain jruby rspec needs JVM flags; use bin/run_rspec, bin/galaaz-jruby, or GALAAZ_JRUBY_OPTS — see lib/galaaz_jruby.rb)
|
|
7
|
+
|
|
8
|
+
require 'galaaz'
|
|
9
|
+
|
|
10
|
+
describe "NilClass when used as R NULL (missing list element → Ruby nil)" do
|
|
11
|
+
|
|
12
|
+
context "nil.is__null" do
|
|
13
|
+
it "does not raise" do
|
|
14
|
+
expect { nil.is__null }.not_to raise_error
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "returns an object that responds to unboxed_get" do
|
|
18
|
+
expect(nil.is__null).to respond_to(:unboxed_get)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "unboxed_get(0) returns true (nil is treated as null)" do
|
|
22
|
+
expect(nil.is__null.unboxed_get(0)).to eq true
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context "nil.isTRUE" do
|
|
27
|
+
it "does not raise" do
|
|
28
|
+
expect { nil.isTRUE }.not_to raise_error
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "unboxed_get(0) returns false (R's isTRUE(NULL) is FALSE)" do
|
|
32
|
+
expect(nil.isTRUE.unboxed_get(0)).to eq false
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context "nil.is__null | nil.isTRUE (as in include_engine)" do
|
|
37
|
+
it "does not raise and unboxed_get(0) is true" do
|
|
38
|
+
result = (nil.is__null | nil.isTRUE).unboxed_get(0)
|
|
39
|
+
expect(result).to eq true
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Phase 2 (performance): Object.build prefers wrapper_tag / r_class; class() probe only as fallback.
|
|
4
|
+
|
|
5
|
+
require 'galaaz'
|
|
6
|
+
|
|
7
|
+
describe 'R::Object.build (Phase 2 — envelope metadata vs class probe)' do
|
|
8
|
+
describe '.build_class_probe_count' do
|
|
9
|
+
it 'does not probe when r_class and wrapper_tag come from eval_r_with_result envelope' do
|
|
10
|
+
vn = R::Support.generate_var_name
|
|
11
|
+
env = R.bridge.eval_r_with_result("#{vn} <- c(1L, 2L, 3L)")
|
|
12
|
+
expect(env[:type]).to eq(:handle)
|
|
13
|
+
expect(env[:wrapper_tag]).to eq('vector')
|
|
14
|
+
|
|
15
|
+
R::Object.reset_build_counters!
|
|
16
|
+
obj = R::Object.build(env[:handle], nil, r_class: env[:r_class], wrapper_tag: env[:wrapper_tag])
|
|
17
|
+
expect(obj).to be_a(R::Vector)
|
|
18
|
+
expect(R::Object.build_class_probe_count).to eq(0)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'does not probe when only r_class is set (legacy envelope)' do
|
|
22
|
+
vn = R::Support.generate_var_name
|
|
23
|
+
env = R.bridge.eval_r_with_result("#{vn} <- list(a = 1L)")
|
|
24
|
+
expect(env[:type]).to eq(:handle)
|
|
25
|
+
|
|
26
|
+
R::Object.reset_build_counters!
|
|
27
|
+
obj = R::Object.build(env[:handle], nil, r_class: env[:r_class], wrapper_tag: nil)
|
|
28
|
+
expect(obj).to be_a(R::List)
|
|
29
|
+
expect(R::Object.build_class_probe_count).to eq(0)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'probes once when neither r_class nor a non-other wrapper_tag is given' do
|
|
33
|
+
vn = R::Support.generate_var_name
|
|
34
|
+
R.bridge.eval_r("#{vn} <- c(10L, 20L)")
|
|
35
|
+
|
|
36
|
+
R::Object.reset_build_counters!
|
|
37
|
+
obj = R::Object.build(vn)
|
|
38
|
+
expect(obj).to be_a(R::Vector)
|
|
39
|
+
expect(R::Object.build_class_probe_count).to eq(1)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'uses r_class for wrapper_tag other without probing (e.g. expression)' do
|
|
43
|
+
vn = R::Support.generate_var_name
|
|
44
|
+
env = R.bridge.eval_r_with_result("#{vn} <- expression(1 + 2)")
|
|
45
|
+
expect(env[:wrapper_tag]).to eq('other')
|
|
46
|
+
|
|
47
|
+
R::Object.reset_build_counters!
|
|
48
|
+
obj = R::Object.build(vn, nil, r_class: env[:r_class], wrapper_tag: env[:wrapper_tag])
|
|
49
|
+
expect(obj).to be_a(R::RExpression)
|
|
50
|
+
expect(R::Object.build_class_probe_count).to eq(0)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Phase 1 (plan): NewBridge callback argument transport + semantic return via galaaz_bridge_env.
|
|
4
|
+
# Fast suite — keep coverage here, not in new_bridge_specs.
|
|
5
|
+
|
|
6
|
+
require 'galaaz'
|
|
7
|
+
|
|
8
|
+
describe 'Phase 1 NewBridge callbacks (adapter proc stub)' do
|
|
9
|
+
def global_callback_handles
|
|
10
|
+
names = R::Support.eval("ls(envir = .GlobalEnv, pattern = '^g2_v[0-9]+$')")
|
|
11
|
+
ruby = names.respond_to?(:to_ruby) ? names.to_ruby : []
|
|
12
|
+
ruby.is_a?(Array) ? ruby : Array(ruby).compact
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
before(:all) do
|
|
16
|
+
R.bridge.eval_r('call_with_arg <- function(f, x) { f(x) }')
|
|
17
|
+
R.bridge.eval_r('call_twice <- function(f, a, b) { f(a); f(b) }')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'passes numeric scalar and returns semantic value from R' do
|
|
21
|
+
result = R.call_with_arg(proc { |x| (x >> 0) + 1 }, 41)
|
|
22
|
+
expect(result).to be_a(R::Object)
|
|
23
|
+
expect(result.to_ruby).to eq(42.0)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'passes character scalar' do
|
|
27
|
+
result = R.call_with_arg(proc { |x| x.to_ruby.to_s.upcase == 'ABC' ? 1 : 0 }, 'abc')
|
|
28
|
+
expect(result.to_ruby).to eq(1.0)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'passes logical scalar' do
|
|
32
|
+
result = R.call_with_arg(proc { |x| x.to_ruby == true ? 7 : 0 }, true)
|
|
33
|
+
expect(result.to_ruby).to eq(7.0)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'passes logical NA (R NA may appear as Ruby nil at the callback boundary)' do
|
|
37
|
+
na1 = R::Support.eval('NA')
|
|
38
|
+
result = R.call_with_arg(proc { |x|
|
|
39
|
+
(x.nil? || (x.respond_to?(:to_ruby) && x.to_ruby.nil?)) ? 1 : 0
|
|
40
|
+
}, na1)
|
|
41
|
+
expect(result.to_ruby).to eq(1.0)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'passes non-scalar argument as boxed R object' do
|
|
45
|
+
result = R.call_with_arg(proc { |x| (x.length >> 0) == 3 ? 1 : 0 }, R.c(1, 2, 3))
|
|
46
|
+
expect(result.to_ruby).to eq(1.0)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'reuses the same callback for two invocations' do
|
|
50
|
+
result = R.call_twice(proc { |x| (x >> 0) + 100 }, 1, 2)
|
|
51
|
+
expect(result).to be_a(R::Object)
|
|
52
|
+
# Last invocation wins as return value of call_twice (f(b) with b=2 -> 102)
|
|
53
|
+
expect(result.to_ruby).to eq(102.0)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'isolates two different callback procs' do
|
|
57
|
+
r1 = R.call_with_arg(proc { |x| (x >> 0) + 1 }, 10)
|
|
58
|
+
r2 = R.call_with_arg(proc { |x| (x >> 0) + 2 }, 10)
|
|
59
|
+
expect(r1.to_ruby).to eq(11.0)
|
|
60
|
+
expect(r2.to_ruby).to eq(12.0)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'does not leak temporary g2_v callback handles in .GlobalEnv' do
|
|
64
|
+
before = global_callback_handles
|
|
65
|
+
|
|
66
|
+
10.times do |i|
|
|
67
|
+
out = R.call_with_arg(proc { |x| (x >> 0) + 1 }, i)
|
|
68
|
+
expect(out.to_ruby).to eq((i + 1).to_f)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
after = global_callback_handles
|
|
72
|
+
expect(after).to eq(before)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'does not create legacy galaaz_bridge_env for callback semantic returns' do
|
|
76
|
+
R::Support.eval("if (exists('galaaz_bridge_env', envir = .GlobalEnv, inherits = FALSE)) rm('galaaz_bridge_env', envir = .GlobalEnv)")
|
|
77
|
+
|
|
78
|
+
out = R.call_with_arg(proc { |x| (x >> 0) + 1 }, 9)
|
|
79
|
+
expect(out.to_ruby).to eq(10.0)
|
|
80
|
+
|
|
81
|
+
exists_legacy = R::Support.eval("exists('galaaz_bridge_env', envir = .GlobalEnv, inherits = FALSE)")
|
|
82
|
+
expect(exists_legacy).to eq(false)
|
|
83
|
+
end
|
|
84
|
+
end
|