iruby 0.4.0 → 0.5.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/.github/workflows/ubuntu.yml +62 -0
- data/CHANGES +24 -0
- data/Gemfile +0 -2
- data/LICENSE +1 -1
- data/README.md +66 -62
- data/Rakefile +10 -10
- data/ci/Dockerfile.main.erb +1 -3
- data/iruby.gemspec +13 -19
- data/lib/iruby.rb +2 -6
- data/lib/iruby/backend.rb +19 -5
- data/lib/iruby/display.rb +57 -41
- data/lib/iruby/formatter.rb +3 -3
- data/lib/iruby/input.rb +6 -6
- data/lib/iruby/input/autoload.rb +1 -1
- data/lib/iruby/input/builder.rb +4 -4
- data/lib/iruby/input/button.rb +2 -2
- data/lib/iruby/input/cancel.rb +1 -1
- data/lib/iruby/input/checkbox.rb +3 -3
- data/lib/iruby/input/date.rb +3 -3
- data/lib/iruby/input/field.rb +2 -2
- data/lib/iruby/input/file.rb +3 -3
- data/lib/iruby/input/form.rb +6 -6
- data/lib/iruby/input/label.rb +4 -4
- data/lib/iruby/input/multiple.rb +10 -10
- data/lib/iruby/input/popup.rb +2 -2
- data/lib/iruby/input/radio.rb +6 -6
- data/lib/iruby/input/select.rb +8 -8
- data/lib/iruby/input/textarea.rb +1 -1
- data/lib/iruby/input/widget.rb +2 -2
- data/lib/iruby/jupyter.rb +1 -0
- data/lib/iruby/kernel.rb +18 -13
- data/lib/iruby/ostream.rb +22 -10
- data/lib/iruby/session_adapter.rb +1 -3
- data/lib/iruby/session_adapter/pyzmq_adapter.rb +11 -10
- data/lib/iruby/utils.rb +4 -0
- data/lib/iruby/version.rb +1 -1
- data/run-test.sh +1 -1
- data/test/helper.rb +90 -0
- data/test/integration_test.rb +1 -2
- data/test/iruby/backend_test.rb +37 -0
- data/test/iruby/command_test.rb +0 -1
- data/test/iruby/jupyter_test.rb +0 -1
- data/test/iruby/mime_test.rb +32 -0
- data/test/iruby/multi_logger_test.rb +0 -1
- data/test/iruby/session_adapter/cztop_adapter_test.rb +1 -1
- data/test/iruby/session_adapter/ffirzmq_adapter_test.rb +1 -1
- data/test/iruby/session_adapter/session_adapter_test_base.rb +1 -3
- data/test/iruby/session_adapter_test.rb +42 -67
- data/test/iruby/session_test.rb +9 -15
- data/test/run-test.rb +18 -0
- metadata +68 -64
- data/.travis.yml +0 -41
- data/CONTRIBUTORS +0 -19
- data/lib/iruby/session/rbczmq.rb +0 -72
- data/lib/iruby/session_adapter/rbczmq_adapter.rb +0 -33
- data/test/iruby/session_adapter/rbczmq_adapter_test.rb +0 -37
- data/test/test_helper.rb +0 -48
data/lib/iruby/input/label.rb
CHANGED
@@ -4,13 +4,13 @@ module IRuby
|
|
4
4
|
needs label: nil, icon: nil
|
5
5
|
|
6
6
|
def widget_label
|
7
|
-
div class: 'iruby-label input-group' do
|
8
|
-
span class: 'input-group-addon' do
|
7
|
+
div class: 'iruby-label input-group' do
|
8
|
+
span class: 'input-group-addon' do
|
9
9
|
text @label || to_label(@key)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
yield
|
13
|
-
|
13
|
+
|
14
14
|
if @icon
|
15
15
|
span @icon, class: "input-group-addon"
|
16
16
|
end
|
data/lib/iruby/input/multiple.rb
CHANGED
@@ -9,7 +9,7 @@ module IRuby
|
|
9
9
|
|
10
10
|
params[:key] = unique_key(key)
|
11
11
|
params[:options] = args
|
12
|
-
|
12
|
+
|
13
13
|
params[:default] = case params[:default]
|
14
14
|
when false, nil
|
15
15
|
[]
|
@@ -24,12 +24,12 @@ module IRuby
|
|
24
24
|
|
25
25
|
def widget_css
|
26
26
|
<<-CSS
|
27
|
-
.iruby-multiple {
|
27
|
+
.iruby-multiple {
|
28
28
|
display: table;
|
29
29
|
min-width: 25%;
|
30
30
|
}
|
31
|
-
.form-control.iruby-multiple-container {
|
32
|
-
display: table;
|
31
|
+
.form-control.iruby-multiple-container {
|
32
|
+
display: table;
|
33
33
|
}
|
34
34
|
CSS
|
35
35
|
end
|
@@ -54,17 +54,17 @@ module IRuby
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def widget_html
|
57
|
-
widget_label do
|
58
|
-
div class: 'form-control iruby-multiple-container' do
|
57
|
+
widget_label do
|
58
|
+
div class: 'form-control iruby-multiple-container' do
|
59
59
|
params = {
|
60
60
|
size: @size,
|
61
61
|
multiple: true,
|
62
|
-
class: 'iruby-multiple',
|
62
|
+
class: 'iruby-multiple',
|
63
63
|
:'data-iruby-key' => @key
|
64
64
|
}
|
65
|
-
|
66
|
-
select **params do
|
67
|
-
@options.each do |o|
|
65
|
+
|
66
|
+
select **params do
|
67
|
+
@options.each do |o|
|
68
68
|
option o, selected: @default.include?(o)
|
69
69
|
end
|
70
70
|
end
|
data/lib/iruby/input/popup.rb
CHANGED
data/lib/iruby/input/radio.rb
CHANGED
@@ -6,7 +6,7 @@ module IRuby
|
|
6
6
|
builder :radio do |*args, **params|
|
7
7
|
key = :radio
|
8
8
|
key, *args = args if args.first.is_a? Symbol
|
9
|
-
|
9
|
+
|
10
10
|
params[:key] = unique_key(key)
|
11
11
|
params[:options] = args
|
12
12
|
params[:default] ||= false
|
@@ -24,7 +24,7 @@ module IRuby
|
|
24
24
|
<<-JS
|
25
25
|
$('.iruby-radio input').change(function(){
|
26
26
|
var parent = $(this).closest('.iruby-radio');
|
27
|
-
$(parent).data('iruby-value',
|
27
|
+
$(parent).data('iruby-value',
|
28
28
|
$(parent).find(':checked').val()
|
29
29
|
);
|
30
30
|
});
|
@@ -38,13 +38,13 @@ module IRuby
|
|
38
38
|
:'data-iruby-value' => @options.first,
|
39
39
|
class: 'iruby-radio form-control'
|
40
40
|
}
|
41
|
-
widget_label do
|
41
|
+
widget_label do
|
42
42
|
div **params do
|
43
43
|
@options.each do |option|
|
44
|
-
label class: 'radio-inline' do
|
44
|
+
label class: 'radio-inline' do
|
45
45
|
input(
|
46
|
-
name: @key,
|
47
|
-
value: option,
|
46
|
+
name: @key,
|
47
|
+
value: option,
|
48
48
|
type: 'radio',
|
49
49
|
checked: @default == option
|
50
50
|
)
|
data/lib/iruby/input/select.rb
CHANGED
@@ -20,7 +20,7 @@ module IRuby
|
|
20
20
|
|
21
21
|
def widget_css
|
22
22
|
<<-CSS
|
23
|
-
.iruby-select {
|
23
|
+
.iruby-select {
|
24
24
|
min-width: 25%;
|
25
25
|
margin-left: 0 !important;
|
26
26
|
}
|
@@ -30,7 +30,7 @@ module IRuby
|
|
30
30
|
def widget_js
|
31
31
|
<<-JS
|
32
32
|
$('.iruby-select').change(function(){
|
33
|
-
$(this).data('iruby-value',
|
33
|
+
$(this).data('iruby-value',
|
34
34
|
$(this).find('option:selected').text()
|
35
35
|
);
|
36
36
|
});
|
@@ -38,16 +38,16 @@ module IRuby
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def widget_html
|
41
|
-
widget_label do
|
42
|
-
div class: 'form-control' do
|
41
|
+
widget_label do
|
42
|
+
div class: 'form-control' do
|
43
43
|
params = {
|
44
|
-
class: 'iruby-select',
|
44
|
+
class: 'iruby-select',
|
45
45
|
:'data-iruby-key' => @key,
|
46
46
|
:'data-iruby-value' => @default
|
47
47
|
}
|
48
|
-
|
49
|
-
select **params do
|
50
|
-
@options.each do |o|
|
48
|
+
|
49
|
+
select **params do
|
50
|
+
@options.each do |o|
|
51
51
|
option o, selected: @default == o
|
52
52
|
end
|
53
53
|
end
|
data/lib/iruby/input/textarea.rb
CHANGED
data/lib/iruby/input/widget.rb
CHANGED
@@ -9,13 +9,13 @@ module IRuby
|
|
9
9
|
def content; widget_html; end
|
10
10
|
|
11
11
|
def self.builder method, &block
|
12
|
-
Builder.instance_eval do
|
12
|
+
Builder.instance_eval do
|
13
13
|
define_method method, &block
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def widget_join method, *args
|
18
|
-
strings = args.map do |arg|
|
18
|
+
strings = args.map do |arg|
|
19
19
|
arg.is_a?(String) ? arg : arg.send(method)
|
20
20
|
end
|
21
21
|
strings.uniq.join("\n")
|
data/lib/iruby/jupyter.rb
CHANGED
data/lib/iruby/kernel.rb
CHANGED
@@ -59,14 +59,21 @@ module IRuby
|
|
59
59
|
@session.send(:reply, :kernel_info_reply,
|
60
60
|
protocol_version: '5.0',
|
61
61
|
implementation: 'iruby',
|
62
|
-
banner: "IRuby #{IRuby::VERSION} (with #{@session.description})",
|
63
62
|
implementation_version: IRuby::VERSION,
|
64
63
|
language_info: {
|
65
64
|
name: 'ruby',
|
66
65
|
version: RUBY_VERSION,
|
67
66
|
mimetype: 'application/x-ruby',
|
68
67
|
file_extension: '.rb'
|
69
|
-
}
|
68
|
+
},
|
69
|
+
banner: "IRuby #{IRuby::VERSION} (with #{@session.description})",
|
70
|
+
help_links: [
|
71
|
+
{
|
72
|
+
text: "Ruby Documentation",
|
73
|
+
url: "https://ruby-doc.org/"
|
74
|
+
}
|
75
|
+
],
|
76
|
+
status: :ok)
|
70
77
|
end
|
71
78
|
|
72
79
|
def send_status(status)
|
@@ -94,6 +101,7 @@ module IRuby
|
|
94
101
|
content = error_content(e)
|
95
102
|
@session.send(:publish, :error, content)
|
96
103
|
content[:status] = :error
|
104
|
+
content[:execution_count] = @execution_count
|
97
105
|
end
|
98
106
|
@session.send(:reply, :execute_reply, content)
|
99
107
|
@session.send(:publish, :execute_result,
|
@@ -103,9 +111,11 @@ module IRuby
|
|
103
111
|
end
|
104
112
|
|
105
113
|
def error_content(e)
|
114
|
+
rindex = e.backtrace.rindex{|line| line.start_with?(@backend.eval_path)} || -1
|
115
|
+
backtrace = SyntaxError === e && rindex == -1 ? [] : e.backtrace[0..rindex]
|
106
116
|
{ ename: e.class.to_s,
|
107
117
|
evalue: e.message,
|
108
|
-
traceback: ["#{RED}#{e.class}#{RESET}: #{e.message}", *
|
118
|
+
traceback: ["#{RED}#{e.class}#{RESET}: #{e.message}", *backtrace] }
|
109
119
|
end
|
110
120
|
|
111
121
|
def is_complete_request(msg)
|
@@ -123,9 +133,10 @@ module IRuby
|
|
123
133
|
end
|
124
134
|
@session.send(:reply, :complete_reply,
|
125
135
|
matches: @backend.complete(code),
|
126
|
-
status: :ok,
|
127
136
|
cursor_start: start.to_i,
|
128
|
-
cursor_end: msg[:content]['cursor_pos']
|
137
|
+
cursor_end: msg[:content]['cursor_pos'],
|
138
|
+
metadata: {},
|
139
|
+
status: :ok)
|
129
140
|
end
|
130
141
|
|
131
142
|
def connect_request(msg)
|
@@ -144,14 +155,8 @@ module IRuby
|
|
144
155
|
end
|
145
156
|
|
146
157
|
def inspect_request(msg)
|
147
|
-
|
148
|
-
@session.send(:reply, :inspect_reply,
|
149
|
-
status: :ok,
|
150
|
-
data: Display.display(result),
|
151
|
-
metadata: {})
|
152
|
-
rescue Exception => e
|
153
|
-
IRuby.logger.warn "Inspection error: #{e.message}\n#{e.backtrace.join("\n")}"
|
154
|
-
@session.send(:reply, :inspect_reply, status: :error)
|
158
|
+
# not yet implemented. See (#119).
|
159
|
+
@session.send(:reply, :inspect_reply, status: :ok, found: false, data: {}, metadata: {})
|
155
160
|
end
|
156
161
|
|
157
162
|
def comm_open(msg)
|
data/lib/iruby/ostream.rb
CHANGED
@@ -25,26 +25,38 @@ module IRuby
|
|
25
25
|
alias_method :next, :read
|
26
26
|
alias_method :readline, :read
|
27
27
|
|
28
|
-
def write(
|
29
|
-
|
30
|
-
|
31
|
-
nil
|
28
|
+
def write(*obj)
|
29
|
+
str = build_string { |sio| sio.write(*obj) }
|
30
|
+
session_send(str)
|
32
31
|
end
|
33
32
|
alias_method :<<, :write
|
34
33
|
alias_method :print, :write
|
35
34
|
|
36
|
-
def printf(*
|
37
|
-
|
35
|
+
def printf(format, *obj)
|
36
|
+
str = build_string { |sio| sio.printf(format, *obj) }
|
37
|
+
session_send(str)
|
38
38
|
end
|
39
39
|
|
40
|
-
def puts(*
|
41
|
-
|
42
|
-
|
43
|
-
nil
|
40
|
+
def puts(*obj)
|
41
|
+
str = build_string { |sio| sio.puts(*obj) }
|
42
|
+
session_send(str)
|
44
43
|
end
|
45
44
|
|
46
45
|
def writelines(lines)
|
47
46
|
lines.each { |s| write(s) }
|
48
47
|
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def build_string
|
52
|
+
StringIO.open { |sio| yield(sio); sio.string }
|
53
|
+
end
|
54
|
+
|
55
|
+
def session_send(str)
|
56
|
+
raise 'I/O operation on closed file' unless @session
|
57
|
+
|
58
|
+
@session.send(:publish, :stream, name: @name, text: str)
|
59
|
+
nil
|
60
|
+
end
|
49
61
|
end
|
50
62
|
end
|
@@ -36,15 +36,13 @@ module IRuby
|
|
36
36
|
|
37
37
|
require_relative 'session_adapter/ffirzmq_adapter'
|
38
38
|
require_relative 'session_adapter/cztop_adapter'
|
39
|
-
require_relative 'session_adapter/rbczmq_adapter'
|
40
39
|
require_relative 'session_adapter/pyzmq_adapter'
|
41
40
|
|
42
41
|
def self.select_adapter_class(name=nil)
|
43
42
|
classes = {
|
44
43
|
'ffi-rzmq' => SessionAdapter::FfirzmqAdapter,
|
45
44
|
'cztop' => SessionAdapter::CztopAdapter,
|
46
|
-
'
|
47
|
-
'pyzmq' => SessionAdapter::PyzmqAdapter
|
45
|
+
# 'pyzmq' => SessionAdapter::PyzmqAdapter
|
48
46
|
}
|
49
47
|
if (name ||= ENV.fetch('IRUBY_SESSION_ADAPTER', nil))
|
50
48
|
cls = classes[name]
|
@@ -1,14 +1,19 @@
|
|
1
1
|
module IRuby
|
2
2
|
module SessionAdapter
|
3
3
|
class PyzmqAdapter < BaseAdapter
|
4
|
-
def self.load_requirements
|
5
|
-
require 'pycall'
|
6
|
-
@zmq = PyCall.import_module('zmq')
|
7
|
-
rescue PyCall::PyError => error
|
8
|
-
raise LoadError, error.message
|
9
|
-
end
|
10
4
|
|
11
5
|
class << self
|
6
|
+
def load_requirements
|
7
|
+
require 'pycall'
|
8
|
+
import_pyzmq
|
9
|
+
end
|
10
|
+
|
11
|
+
def import_pyzmq
|
12
|
+
@zmq = PyCall.import_module('zmq')
|
13
|
+
rescue PyCall::PyError => error
|
14
|
+
raise LoadError, error.message
|
15
|
+
end
|
16
|
+
|
12
17
|
attr_reader :zmq
|
13
18
|
end
|
14
19
|
|
@@ -20,10 +25,6 @@ module IRuby
|
|
20
25
|
make_socket(:PUB, protocol, host, port)
|
21
26
|
end
|
22
27
|
|
23
|
-
def make_pub_socket(protocol, host, port)
|
24
|
-
make_socket(:REP, protocol, host, port)
|
25
|
-
end
|
26
|
-
|
27
28
|
def heartbeat_loop(sock)
|
28
29
|
PyCall.sys.path.append(File.expand_path('../pyzmq', __FILE__))
|
29
30
|
heartbeat = PyCall.import_module('iruby.heartbeat')
|
data/lib/iruby/utils.rb
CHANGED
data/lib/iruby/version.rb
CHANGED
data/run-test.sh
CHANGED
data/test/helper.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require "iruby"
|
2
|
+
require "test/unit"
|
3
|
+
require "test/unit/rr"
|
4
|
+
require "tmpdir"
|
5
|
+
|
6
|
+
module IRubyTest
|
7
|
+
class TestBase < Test::Unit::TestCase
|
8
|
+
def assert_output(stdout=nil, stderr=nil)
|
9
|
+
flunk "assert_output requires a block to capture output." unless block_given?
|
10
|
+
|
11
|
+
out, err = capture_io do
|
12
|
+
yield
|
13
|
+
end
|
14
|
+
|
15
|
+
y = check_assert_output_result(stderr, err, "stderr")
|
16
|
+
x = check_assert_output_result(stdout, out, "stdout")
|
17
|
+
|
18
|
+
(!stdout || x) && (!stderr || y)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def capture_io
|
24
|
+
captured_stdout = StringIO.new
|
25
|
+
captured_stderr = StringIO.new
|
26
|
+
|
27
|
+
orig_stdout, $stdout = $stdout, captured_stdout
|
28
|
+
orig_stderr, $stderr = $stderr, captured_stderr
|
29
|
+
|
30
|
+
yield
|
31
|
+
|
32
|
+
return captured_stdout.string, captured_stderr.string
|
33
|
+
ensure
|
34
|
+
$stdout = orig_stdout
|
35
|
+
$stderr = orig_stderr
|
36
|
+
end
|
37
|
+
|
38
|
+
def check_assert_output_result(expected, actual, name)
|
39
|
+
if expected
|
40
|
+
message = "In #{name}"
|
41
|
+
case expected
|
42
|
+
when Regexp
|
43
|
+
assert_match(expected, actual, message)
|
44
|
+
else
|
45
|
+
assert_equal(expected, actual, message)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def ignore_warning
|
51
|
+
saved, $VERBOSE = $VERBOSE , nil
|
52
|
+
yield
|
53
|
+
ensure
|
54
|
+
$VERBOSE = saved
|
55
|
+
end
|
56
|
+
|
57
|
+
def with_env(env)
|
58
|
+
keys = env.keys
|
59
|
+
saved_values = ENV.values_at(*keys)
|
60
|
+
ENV.update(env)
|
61
|
+
yield
|
62
|
+
ensure
|
63
|
+
if keys && saved_values
|
64
|
+
keys.zip(saved_values) do |k, v|
|
65
|
+
ENV[k] = v
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def windows_only
|
71
|
+
omit('windows only test') unless windows?
|
72
|
+
end
|
73
|
+
|
74
|
+
def apple_only
|
75
|
+
omit('apple only test') unless windows?
|
76
|
+
end
|
77
|
+
|
78
|
+
def unix_only
|
79
|
+
omit('unix only test') if windows? || apple?
|
80
|
+
end
|
81
|
+
|
82
|
+
def windows?
|
83
|
+
/mingw|mswin/ =~ RUBY_PLATFORM
|
84
|
+
end
|
85
|
+
|
86
|
+
def apple?
|
87
|
+
/darwin/ =~ RUBY_PLATFORM
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|